use*_*490 12 c++ constructor type-conversion c++11
在C++ 11中,没有explicit关键字的构造函数可用于将参数列表隐式转换为其类.例如:
class Date{
private:
int d, m, y;
public:
Date(int _d, int _m=0, int _y=0) : m(_m), d(_d), y(_y) {}
friend bool operator==(const Date &x, const Date &y) {return x.d==y.d;}
};
int main()
{
Date x = {1,2,3}; // no error; using converting constructor
x == 1; // no error; converting constructor turns int into Date object
x == {1,2,3}; // error
}
Run Code Online (Sandbox Code Playgroud)
因为x == {1,2,3},我收到以下错误:
explicit.cc:16:10: error: expected primary-expression before ‘{’ token
x=={1,2,3};
^
Run Code Online (Sandbox Code Playgroud)
我想知道为什么转换构造函数不会将列表转换{1,2,3}为Date对象?特别是因为x == 1不会导致错误,为什么x == {1,2,3}呢?
Bar*_*rry 15
你可能会特别惊讶:
x = {1, 2, 3}; // ok
x == {1, 2, 3}; // error
operator==(x, {1, 2, 3}); // ok
Run Code Online (Sandbox Code Playgroud)
这是因为只有特定的地方允许使用braced-init-list(基本上是逗号分隔的东西之间的列表{}s).它可以在右侧,=因为规则说它可以.它可以用作函数调用表达式中的参数,因为规则说它可以.但它不能在比较运算符的任何一方使用,因为规则不允许它.
我不知道这背后是否有一个根本原因,可能不是强烈需要它.
为了完成巴里的回答,我列出了所有brace-init-list可以出现a 的语句或表达式:
func({/*...*/},arg2)obj[{/*...*/}];type{/*...*/}new type{/*...*/}a = {/*...*/}; b += {/*...*/};...while (atype i={/*.../*})for(auto it:{/*...*/})return {/*.../*}如果推导出返回类型,则不是)atype a{/*...*}; atype b={/*.../*};或包括成员初始值设定项:a_memb{/*.../*}void f(atype a={/*.../*})