You could use std::find_if algorithm:

Person * lookForName(vector<Person*> &names, const std::string& input)
{
    auto it = std::find_if(names.begin(), names.end(),
              &input{ return p->getName() == input; });


    return it != names.end() ? *it : nullptr; // if iterator reaches names.end(), it's not found
}

For C++03 version:

struct isSameName
{
    explicit isSameName(const std::string& name)
    : name_(name)
    {
    }

    bool operator()(Person* p)
    {
       return p->getName() == name_;
    }
    std::string name_;
};

Person * lookForName(vector<Person*> &names, const std::string& input)
{
    vector<Person*>::iterator it = std::find_if(names.begin(), names.end(),
                           isSameName(input));


    return it != names.end() ? *it : NULL;
}
Answer from billz on Stack Overflow
🌐
Reddit
reddit.com › r/cpp_questions › returning reference of null pointer
r/cpp_questions on Reddit: Returning reference of NULL pointer
July 18, 2021 -

In following function I'm trying find a node in Binary tree that matches the key. I'm passing reference node pointer as smart pointer and this function returns a refernce to node pointer.

How can I return NULL ? As the return value of function is std::unique_ptr<node>& so it is supposed to return a reference.

std::unique_ptr<node>& BST::ReturnNodePrivate(const int& key, std::unique_ptr<node> &ptr){
    if(NULL != ptr){
        if(ptr->key == key){
            return ptr;
         } 
    } 
     else{ 
        return NULL; 
     } 
}

How can I return NULL ?

🌐
GeeksforGeeks
geeksforgeeks.org › c++ › understanding-nullptr-c
Understanding nullptr in C++ - GeeksforGeeks
There are some unspecified things ... by < and > returns false and comparing any pointer type with nullptr by == and != returns true or false ......
Published   April 5, 2024
🌐
Quora
quora.com › How-do-you-return-a-null-pointer-in-C
How to return a null pointer in C - Quora
Answer (1 of 7): “How do you return a null pointer in C?” This will do it: [code]return (void*)0; [/code]Enjoy your null pointer!
Top answer
1 of 10
57

You cannot do this during references, as they should never be NULL. There are basically three options, one using a pointer, the others using value semantics.

  1. With a pointer (note: this requires that the resource doesn't get destructed while the caller has a pointer to it; also make sure the caller knows it doesn't need to delete the object):

    SomeResource* SomeClass::getSomething(std::string name) {
        std::map<std::string, SomeResource>::iterator it = content_.find(name);
        if (it != content_.end()) 
            return &(*it);  
        return NULL;  
    }
    
  2. Using std::pair with a bool to indicate if the item is valid or not (note: requires that SomeResource has an appropriate default constructor and is not expensive to construct):

    std::pair<SomeResource, bool> SomeClass::getSomething(std::string name) {
        std::map<std::string, SomeResource>::iterator it = content_.find(name);
        if (it != content_.end()) 
            return std::make_pair(*it, true);  
        return std::make_pair(SomeResource(), false);  
    }
    
  3. Using boost::optional:

    boost::optional<SomeResource> SomeClass::getSomething(std::string name) {
        std::map<std::string, SomeResource>::iterator it = content_.find(name);
        if (it != content_.end()) 
            return *it;  
        return boost::optional<SomeResource>();  
    }
    

If you want value semantics and have the ability to use Boost, I'd recommend option three. The primary advantage of boost::optional over std::pair is that an unitialized boost::optional value doesn't construct the type its encapsulating. This means it works for types that have no default constructor and saves time/memory for types with a non-trivial default constructor.

I also modified your example so you're not searching the map twice (by reusing the iterator).

2 of 10
31

Why "besides using pointers"? Using pointers is the way you do it in C++. Unless you define some "optional" type which has something like the isNull() function you mentioned. (or use an existing one, like boost::optional)

References are designed, and guaranteed, to never be null. Asking "so how do I make them null" is nonsensical. You use pointers when you need a "nullable reference".

🌐
GitHub
github.com › swig › swig › issues › 1154
return nullptr for std::shared_ptr does not work · Issue #1154 · swig/swig
November 16, 2017 - Hi When using raw pointers from a c++ method: class Foo { void doSometing(); } Foo *getFoo() { return nullptr; } In python this results in: f = getFoo() # works just fine assert f == None If I try to call f.doSomething() I get a proper e...
Author   swig
Find elsewhere
🌐
Microsoft Learn
learn.microsoft.com › en-us › cpp › extensions › nullptr-cpp-component-extensions
nullptr (C++/CLI and C++/CX) | Microsoft Learn
June 25, 2025 - The following code example shows that casting nullptr is allowed and returns a pointer or handle to the cast type that contains the nullptr value.
🌐
cppreference.com
en.cppreference.com › cpp › language › nullptr
nullptr, the pointer literal (since C++11) - cppreference.com
August 12, 2024 - Demonstrates that nullptr retains the meaning of null pointer constant even if it is no longer a literal. Run this code · #include <cstddef> #include <iostream> template<class T> constexpr T clone(const T& t) { return t; } void g(int*) { std::cout << "Function g called\n"; } int main() { g(nullptr); // Fine g(NULL); // Fine g(0); // Fine g(clone(nullptr)); // Fine // g(clone(NULL)); // ERROR: non-literal zero cannot be a null pointer constant // g(clone(0)); // ERROR: non-literal zero cannot be a null pointer constant } Output: Function g called Function g called Function g called Function g called ·
Top answer
1 of 9
76

In C++, references can't be null. If you want to optionally return null if nothing is found, you need to return a pointer, not a reference:

Attr *getAttribute(const string& attribute_name) const {
   //search collection
   //if found at i
        return &attributes[i];
   //if not found
        return nullptr;
}

Otherwise, if you insist on returning by reference, then you should throw an exception if the attribute isn't found.

(By the way, I'm a little worried about your method being const and returning a non-const attribute. For philosophical reasons, I'd suggest returning const Attr *. If you also may want to modify this attribute, you can overload with a non-const method returning a non-const attribute as well.)

2 of 9
57

There are several possible answers here. You want to return something that might exist. Here are some options, ranging from my least preferred to most preferred:

  • Return by reference, and signal can-not-find by exception.

    Attr& getAttribute(const string& attribute_name) const 
    {
       //search collection
       //if found at i
            return attributes[i];
       //if not found
            throw no_such_attribute_error;
    }

It's likely that not finding attributes is a normal part of execution, and hence not very exceptional. The handling for this would be noisy. A null value cannot be returned because it's undefined behaviour to have null references.

  • Return by pointer

    Attr* getAttribute(const string& attribute_name) const 
    {
       //search collection
       //if found at i
            return &attributes[i];
       //if not found
            return nullptr;
    }

It's easy to forget to check whether a result from getAttribute would be a non-NULL pointer, and is an easy source of bugs.

  • Use Boost.Optional

    boost::optional<Attr&> getAttribute(const string& attribute_name) const 
    {
       //search collection
       //if found at i
            return attributes[i];
       //if not found
            return boost::optional<Attr&>();
    }

A boost::optional signifies exactly what is going on here, and has easy methods for inspecting whether such an attribute was found.


Side note: std::optional was recently voted into C++17, so this will be a "standard" thing in the near future.

🌐
Unreal Engine
forums.unrealengine.com › development › programming & scripting › c++
Why does this Pointer return nullptr in a Function but in a begin play function works fine - C++ - Epic Developer Community Forums
July 23, 2021 - APlayerController* OurPlayerController = UGameplayStatics::GetPlayerController(this, 0); Can someone explain to me why this pointer returns the correct playercontroller in the Begin Play Function but when I use the same code in a custom function I call from another class it returns nullptr?
Top answer
1 of 4
9

Returning NULL in case of success (the most simple case for success at that) is definitely contrary to what most people will expect.

Returning a pointer that the user has to manually destruct isn’t super great either. I’d suggest using C++11 unique_ptr but using C++11 may not be feasible in your case.

One thought I had is to make TestRoute private and have the Planner call it whenever it computes a new route.

If the test fails, return NULL, otherwise return the route.

What’s nice about this approach is that you can implement TestRoute however you (or your colleague) please, and the user of the class won’t need to know the details of how it is implemented. The user will just ask for a route from point A to point B and will be guaranteed it’s a valid route with refueling points so long as they don’t receive NULL.

You could also split your method into a few different methods if the performance hit isn’t too great.

For example, for TestRoute, have it return true if the route is possible, false if not.

bool TestRoute(const Route* r)

Have another method TestRouteNeedRefuel that returns true if the route will require refueling, false if not

bool TestRouteNeedRefuel(const Route* r)

Then have a final method, GenerateRefuelRoute that returns a new route with the proper refuel points

Route* TestRoute(const Route* r)
//use this if at all possible
std::unique_ptr<Route> TestRoute(const Route* r)

As far as performance goes, remember to profile before making assumptions. If your colleague is worried about copying Route more than needed (and he may have good reason to, as we don't know how expensive it is or what the target platform is) then clearly performance is an important requirement. I would suggest first implementing as clean an interface as can be done, profiling to find where the bottlenecks REALLY are, and then implementing a few speed hacks where necessary.

2 of 4
8

I would generally consider returning a pointer from a method in C++ a bad design, and mixing error states and payload data in the return value, too; this is a recipe for unmaintainable code.

Suggested change: Return the fail/success status as int value (or use ternary logic, e. g. boost::tribool), and pass the argument as non-const reference:

/** @returns
    - 1 if a solution has been found. The argument will be updated.
    - 0 if the request has been processed sucessfully, 
      but no (immediate) solution has been found.
      The argument is not modified in this case.
    - -1 if the request failed. The argument is not modified. */
int findSolution(MyClass& argument);

Usage example, leaving out premature optimization to avoid "unnecessary" copies:

MyClass objectToTest(originalUnmutableObject);

switch(findSolution(objectToTest))
{
    case 1:
        //Replace original with updated object, or whatever
        break;
    case 0:
        //Nothing to do (?)
        break;
    case -1:
        //Error handling
        break;
    default:
        //Unexpected return value
        assert(false);
}

An alternative, more sophisticated and reusable approach could be to bundle error state and object into a generic result class; this pattern was inspired by Rust. I leave the implementation of Result to you.

template<typename T>
class Result
{
    public:
        Result() = delete;
        Result(int error);
        Result(const T& data);
        Result(T&& data);

        //Methods
        bool isOk() const;
        bool isError(int error) const;
        int error() const;
        const T& data() const;

    private:
        //Variables
        int m_error = 0;
        T m_data;
};

...

Result<MyClass> findSolution(const MyClass& argument)
{
    int errorCode = 0;

    ...

    if(errorCode != 0)
        return Result(errorCode);
    else if(solutionFound)
        //Error code of result will be 0, Result::isOk() == true
        return Result(update(argument, solution));
    else
        //Error code of result will be 1, Result::isOk() == false
        return Result(1);
}
🌐
Scaler
scaler.com › home › topics › what is nullptr in c++?
What is nullptr in C++? - Scaler Topics
May 4, 2023 - Return type resolver is also known as Return type overloading which is used to deduce the type of the object being initialized or assign to and uses templatized conversion operator.
Top answer
1 of 5
3

Since both are pointing to the same object, if either obj or d_header is changed, the change will be reflected in the other.

That is incorrect. If the contents of what they point to is changed, that change can be seen through either pointer but if one of them is changed so that it points to something different, the other will still point to the previous object.

Simple example:

int i = 10;
int j = 20;

int* ptr1 = &i;
int* ptr2 = ptr1;

At this point, both the pointers point to the same object, i. Value of i can be changed by:

  1. Directly by assigning a value to i.

     i = 15;
    
  2. Indirectly by assigning a value to where ptr1 points to.

     *ptr1 = 15;
    
  3. Indirectly by assigning a value to where ptr2 points to.

     *ptr2 = 15;
    

However, you can change where ptr1 points to by using:

ptr1 = &j;

Now, ptr1 points to j but ptr2 still points to i.

Any changes made to i will be visible through ptr2 but not ptr1.
Any changes made to j will be visible through ptr1 but not ptr2.

Isn't obj also pointing to null, since both object were pointing to the same object?

The answer should be clear now. obj continues to point to what d_header used to point to. It is not NULL.

So what is the deal of returning a Null pointer?

The function does not necessarily return a NULL pointer. The function returns whatever d_header used to point to before it was changed to be nullptr. It could be a NULL pointer if d_header used to be NULL before the call to the function.

is nullptr in this case would be the same as delete?

No, it is not. There are two different operations. Assigning a pointer to nullptr does not automatically mean that delete gets called on the pointer. If you need to deallocate memory that a pointer points to, you'll have to call to call delete explicitly.

2 of 5
2

Q: "Isn't obj also pointing to null, since both object were pointing to the same object?"

No, both obj and d_heater contain addresses in memory. Changing one does not change the other. This is easy to see if you think about non-pointer variables:

int foo = 13;
int bar = foo;
foo = 42;

Obviously we know that bar still holds 13, and in the same way obj still holds the original address.

If you want obj to keep the same value as d_heater you can make it a reference, then obj and d_heater are the same variable they don't simply share the same value. We can see this again looking at non-pointer variables, but this time let's make bar a reference:

int foo = 13;
int& bar = foo;
foo = 42;

Now both foo and bar will equal 42. If you want to accomplish the same thing with obj make it a pointer reference:

WaterHeater*& obj = d_heater;

You can see a more detailed example here: http://ideone.com/I8CTba

Q. "Is nullptr in this case would be the same as delete?"

No, again d_heater is only an address. If you assign a new value to d_heater it is simply referencing a different point in memory. If by reassigning d_heater you lose the address of dynamically allocated memory that's very bad, it's known as a memory leak. To prevent leaking you must always release dynamically allocated memory before losing the last address to your dynamically allocated memory (call delete for memory allocated with new.)

That said, use of dynamic memory allocation is best left to the standard libraries, unless you really know what you're doing. So I'd strongly recommend you look at using auto-pointers. In C++11 those are unique_ptr and shared_ptr.

🌐
GitHub
github.com › ThePhD › sol2 › issues › 159
Behavior of returning nullptr not explained clearly · Issue #159 · ThePhD/sol2
August 3, 2016 - std::shared_ptr<SomeType> MyFunction() { if (!something) return nullptr; // or std::shared_ptr<SomeType>(); return std::make_shared<SomeType>(1, 2, 3); }
Author   ThePhD
🌐
Cplusplus
cplusplus.com › forum › beginner › 278740
Return NULL in C++ - C++ Forum
if for some reason you can't use that ^^ the 2 main alternatives would be to make a bogus book to return or to return the array index as -1 for not found, index if found, make the finder int instead of book type, and then you can call THAT from a more public function that handles the -1 or index in a little wrapper for the user.
🌐
Eskimo
eskimo.com › ~scs › cclass › notes › sx10d.html
10.4 Null Pointers
Otherwise, we go around the outer loop again, to try another starting position. If we run out of those (if *start == '\0'), without finding a match, we return a null pointer.