I have a function has a return type of std::string& and how do I return a NULL string& if no condition matches in the function?
std::string& SomeClass::getSomething()
{
if(){...}
else if(){...}
// return a NULL
}
C++ references cannot be null.
If you are returning a reference to an object whose lifetime is not tied to the scope of the function call, like a data member, you can safely return a raw pointer (I would recommend a pointer to const).
std::string const* foo::bar() const {
if (condition) {
return &some_data_member;
} else {
return nullptr;
}
}
If not, the best solution is to use a wrapper type like boost::optional (or std::optional in C++17). This not only allows you to return an optional object by value (which may be more performant), but is also self-documenting.
std::optional<std::string> foo::bar() const {
if (condition) {
return "hello, world";
} else {
return std::nullopt;
}
}
Alternatively, you could return a pointer, which can be null. However, returning a raw pointer raises the question of who is responsible for deleting the dynamically allocated string. In this case, returning a std::unique_ptr would be the best option, as ownership is explicitly passed to the caller.
std::unique_ptr<std::string> foo::bar() const {
if (condition) {
return std::make_unique<std::string>("hello, world");
} else {
return nullptr;
}
}
Or even simpler, you could return an empty string, if this is possible in your case. And honestly, this is my preferred approach (KISS).
std::string foo::bar() const {
if (condition) {
return "hello, world";
} else {
return "";
}
}
Anyway you wouldn't return NULL but nullptr.
Also, you should be carefull with returning references from a function and make sure the reference referes to a valid, living object. returning reference to local object is wrong.
you can't return nullptr since nullptr is a pointer and string& is a reference - different types.
your options are:
boost::optional, etc.)personally, if I know there is a strong possibility the function may fail, I would pass the result to a reference type argument and return bool to indicate success of failure
bool SomeClass::getSomething(std::string& result)
{
if(){result = "success 1"; return true; }
else if(){result = "success 2"; return true; }
return false.
}
TryParse,TryGetValue it's cool and modern, but on C++ it's suddenly ancient and ugly?TryParse and TryGetValue are "cool and modern"? (Hint: I didn't) (Another hint: those are ancient and ugly, too)Returning the empty string '' might make sense here.
From your code fragment I'd be wondering if you are peeking under the covers of the class to make a decision that the class itself should be making. See the Martin Fowler's article about "Tell, don't Ask" which also refers to the original article on this by The Pragmatic Programmers.
As stated in comments by juanchopanza, you can't.
If you need to test for NULL you could re-think your approach using a smart pointer. For instance a std::shared_ptr<std::string>:
std::shared_ptr<std::string> SomeClass::getSomething()
{
std::shared_ptr<std::string> stringPtr;
if(){
//...
stringPtr = std::make_shared<std::string>("Whatever string goes here");
}
else if(){
//...
stringPtr = std::make_shared<std::string>("The other string...");
}
return stringPtr;
}
Then you could just test the std::shared_ptrwith its implicit conversion to bool:
auto strReturnedPtr = someClassObj.getSomething();
if (strReturnedPtr)
{
// Do stuff
}
shared_ptr to show usage with smart pointers, don't know the OP context. I should have also mentioned unique_ptr as already proposed in another answer. Anyway in retrospective, a smart pointer seems overkill in this case.
std::string. You need to re-think your approach.boost::optional