Home > Enterprise >  why std::is_constructible will return false if reference type is not match?
why std::is_constructible will return false if reference type is not match?

Time:01-06

I'm currently studying some template stuffs. But I got a question. I have a class like this

class myobj{
    public:
    int val;
    char single;
    string name;
    myobj(){}
    myobj(int a):val(a){};
    myobj(int a, char b, string& c): val(a), single(b), name(move(c)){};

};

And here is the main function

int main(){
    cout << is_constructible<myobj, int>::value << endl; //true
    cout << is_constructible<myobj, int, char, string>::value << endl; //false
    cout << is_constructible<myobj, int, char, string&>::value << endl; //true
    return 0;
}

I can not understand why the second will be false. Is that mean I can not use a string to construct the object? When the function signature shows the parameter is pass-by-reference, I think it is OK to pass an value to it. Is there any misunderstanding about the reference?

CodePudding user response:

You can try it:

myobj(1, 'c', std::string{"lalala"});

This is a string yeah, so it should compile? No:

error: cannot bind non-const lvalue reference of type 'std::string&' {aka 'std::__cxx11::basic_string<char>&'} to an rvalue of type 'std::string' {aka 'std::__cxx11::basic_string<char>'}
   20 |     myobj(1, 'c', std::string{"lalala"});

Live example

string in this context can refer to an rvalue, but an rvalue cannot be referenced by a normal lvalue reference. A string& must be mutable, so there is a difference (a very strong one) between string and string&.

  • Related