使用大括号初始化进行赋值的类型推导规则是什么?
What is the rule for type deduction for assignment using brace initialization?
在下面的代码中,令我惊讶的是,{ }
似乎创建了 int
的默认初始化实例,而不是 A
。
struct A {
int i = 1;
A() = default;
A& operator=(const A& a) {
this->i = a.i;
return *this;
}
A& operator=(int i) {
this->i = i;
return *this;
}
};
int main() {
A a;
a = { };
return a.i;
}
用什么规则解析a = { }
?我认为 a = { }
必须等同于 a = decltype(a){ }
.
此处发生的初始化类型的正确术语是什么?
这是一个 example 神栓。在 -O0
处,程序集准确显示了正在使用的函数。除非删除 int
赋值运算符,否则会调用 A::operator=(int)
。
首先,braced-init-list {}
可用于初始化 int
和 A
,它们也被视为转换,而 [=10] 的转换=] 到 int
在重载决策中获胜,因为从 {}
到 A
的转换(通过 A::A()
)被认为是用户定义的转换。
赋值运算符并不特殊,编译器只是收集重载集中所有可行的operator=
,然后通过重载决策来决定应该选择哪一个。如果你添加另一个 operator=(float)
你会得到一个不明确的错误,因为从 {}
到 int
和从 {}
到 float
的转换都被认为是标准转换相同排名,胜过用户定义的转换。
在下面的代码中,令我惊讶的是,{ }
似乎创建了 int
的默认初始化实例,而不是 A
。
struct A {
int i = 1;
A() = default;
A& operator=(const A& a) {
this->i = a.i;
return *this;
}
A& operator=(int i) {
this->i = i;
return *this;
}
};
int main() {
A a;
a = { };
return a.i;
}
用什么规则解析a = { }
?我认为 a = { }
必须等同于 a = decltype(a){ }
.
此处发生的初始化类型的正确术语是什么?
这是一个 example 神栓。在 -O0
处,程序集准确显示了正在使用的函数。除非删除 int
赋值运算符,否则会调用 A::operator=(int)
。
首先,braced-init-list {}
可用于初始化 int
和 A
,它们也被视为转换,而 [=10] 的转换=] 到 int
在重载决策中获胜,因为从 {}
到 A
的转换(通过 A::A()
)被认为是用户定义的转换。
赋值运算符并不特殊,编译器只是收集重载集中所有可行的operator=
,然后通过重载决策来决定应该选择哪一个。如果你添加另一个 operator=(float)
你会得到一个不明确的错误,因为从 {}
到 int
和从 {}
到 float
的转换都被认为是标准转换相同排名,胜过用户定义的转换。