为何std::is_constructible在引用类型不匹配时会返回false?
关于
is_constructible与非const左值引用参数的疑问 你遇到的问题核心在于C++中非const左值引用的绑定规则,下面直接拆解原因:
为什么第二个检查返回false?
你的myobj第三个构造函数的参数是string&(非const左值引用),而is_constructible<myobj, int, char, string>::value的本质是检查:能否用**string类型的右值(比如临时对象)**去匹配这个构造函数的参数。
但C++明确规定:非const左值引用无法绑定到右值。临时的string对象属于右值,没法被string&接收,因此is_constructible判定这种构造方式不可行,返回false。
而is_constructible<myobj, int, char, string&>::value返回true,是因为这里的模板参数是左值引用类型,对应传递的是可修改的左值(比如一个已定义的string变量),完全符合string&的绑定要求。
关于引用的误解修正
你之前认为“传递值给引用参数可行”,这个结论只适用于const左值引用或右值引用:
const string&既可以绑定左值,也可以绑定右值;- 非const左值引用(
string&)只能绑定到可被修改的左值,临时对象、字面量这类右值都不行。
验证修改方案
如果把构造函数的第三个参数改成const string&,那么所有场景的构造检查都会返回true:
class myobj{ public: int val; char single; string name; myobj(){} myobj(int a):val(a){}; // 修改为const左值引用 myobj(int a, char b, const string& c): val(a), single(b), name(c){}; };
附上你的原始代码:
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)){}; }; 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; }
内容的提问来源于stack exchange,提问作者Kevin eyeson
相关产品推荐
相关产品推荐

