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"});
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&
.