直接初始化中的转换运算符
Conversion operator in direct-initialization
C++14标准(N4296)在8.5/17.6.1中说
如果初始化是直接初始化 [...],则考虑构造函数。枚举适用的构造函数,并且最好的 一个是通过过载分辨率选择的。[...]如果没有构造函数 适用,或者重载解析不明确,则初始化格式不正确。
因此,在直接初始化中,只考虑构造函数 - 忽略转换函数。在下面的代码中没有适用的A
构造函数,只有来自B
的转换函数。但是,代码编译,为什么?
struct A{};
struct B{
operator A(){ return A{}; }
};
int main() {
B b;
A a(b); // direct-initialization
}
您是正确的,在执行A a(b);
时仅考虑A
的构造函数。 [over.match.ctor]/1 状态
当类类型的对象是直接初始化、从相同表达式或派生类类型 ([dcl.init]) 复制初始化或默认初始化时,重载解析将选择构造函数。对于不在复制初始化上下文中的直接初始化或默认初始化,候选函数都是要初始化的对象类的所有构造函数。对于复制初始化(包括复制初始化上下文中的默认初始化),候选函数是该类的所有转换构造函数 ([class.conv.ctor])。参数列表是初始值设定项的表达式列表或赋值表达式。
强调我的
这意味着A()
、A(const A&)
和A(A&&)
是候选列表。 然后我们有 [over.match.viable]/4
[...]第三,为了使 F 成为一个可行的函数,每个参数都应该存在一个隐式转换序列,该序列将该参数转换为 F 的相应参数。
这允许将b
隐式转换为A
,以便可以调用A(A&&)
。
相关文章:
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 构造函数和转换运算符之间的重载解析
- 分配给转换运算符失败-C++
- 转换运算符不适用于sleep_until
- 继承模板化转换运算符
- 模板转换运算符在 clang 6 和 clang 7 之间的区别
- 如何在模板化转换运算符中消除此构造的歧义?
- 为什么选择转换运算符的重载?
- 如何避免强制转换运算符 () 和访问运算符 [] 冲突?
- 如果可能的话,C++总是更喜欢右值引用转换运算符而不是常量左值引用吗?
- 了解转换运算符的选择C++
- 多个隐式转换运算符
- 这个typedef和转换运算符语法是什么意思
- 为什么转换运算符调用复制构造函数两次,而等效函数只调用它一次
- 类模板忽略了用户定义的转换运算符(非模板不忽略)
- 为什么在std::for_each()返回时调用转换运算符
- 为什么 std::optional 的强制转换运算符被忽略了
- 使用用户定义的转换运算符推导函数模板参数
- 模板转换运算符的分辨率不明确
- 统一初始化是隐式发生的,即使 int 强制转换运算符是使用 explicit 关键字声明的.原因是什么?