Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

function call ambiguity with pointer, reference and constant reference parameter

What I am trying to do is, allow a pointer, reference or constant reference to be passed with the setter function:

class A{
    std::string * p;
    std::string st;

    public:
    A():p(0)
    {}
    A& setS(const std::string& s){
        std::cout<<"called with const std::string&\n";
        st = s;
        p = &st;
        return *this;
    }
    A& setS(std::string& s) {
        std::cout<<"called with std::string&\n";
        p = &s;
        return *this; 
    }
    A& setS(std::string* s) {
        std::cout<<"called with std::string*\n";
        p = s;
        return *this; 
    }
};

int main(){
   std::string s;
   A a;
   a.setS(std::move(s)) //const std::string&
    .setS("")           //const std::string&
    .setS(s)            //std::string&
    .setS(0);           //std::string*
    //if std::string* version is not defined,
    //setS(0) calls the const std::string& version and throws exception 
    return 0;
}

But I have seen that, if the pointer version is not there, the setS(0) calls the const std::string& version of the setS() function.

Is there any ambiguity between the pointer and the reference versions or among any others that matter? Is it well defined and expected to work the same way in all compilers?

like image 237
Jahid Avatar asked May 28 '26 16:05

Jahid


1 Answers

There is no ambiguity. When you have A& setS(std::string* s) in the overload set then setS(0) calls the pointer version and 0 is a null pointer. It would be the equivelent of setS(nullptr).

When A& setS(std::string* s) is not in the overload set then the compiler looks to see if there is a way it can construct a temporary string from 0 and then pass that to A& setS(const std::string& s) since a const& can bind to a temporary. std::string can be constructed from a single pointer and again 0 it tread as a null pointer. So you get a temporary null pointer constructed std::string passed to the const& function.

This is undefined behavior though. The constructor for std::string requires that the pointer passed to it be a null terminated c string. If it is not then the behavior is undefined.

like image 102
NathanOliver Avatar answered May 30 '26 06:05

NathanOliver



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!