为何代码中A转int的转换被优先选择而非转vector<int>?
问题解析:为什么
std::vector<int> b{add()}优先选择A到int的转换? 首先看代码行为:std::vector<int> b{add()}最终仅包含1个元素,说明编译器选择了A::operator int()转换,把A对象转成int后作为vector初始化列表的单个元素,而非选择A::operator std::vector<int>()直接转成vector来初始化b。
核心原因:列表初始化的重载决议两阶段规则
C++中,类类型的列表初始化(用{})会按照两阶段进行构造函数的重载决议:
- 第一阶段:仅考虑类的初始化列表构造函数(即接受
std::initializer_list<T>的构造函数)。此时编译器会尝试把初始化列表中的元素转换成initializer_list的元素类型,匹配构造函数。- 对于
std::vector<int>来说,它的初始化列表构造函数是vector(std::initializer_list<int>)。这里初始化列表是{add()},add()返回的A对象可以通过operator int()隐式转换成int,完全满足这个构造函数的参数要求,因此这个构造函数在第一阶段就是可行的。
- 对于
- 第二阶段:只有当第一阶段没有找到任何可行的初始化列表构造函数时,才会考虑类的其他构造函数(比如拷贝构造、移动构造、接受单个参数的构造函数等)。
在你的代码中,第一阶段已经找到可行的初始化列表构造函数,因此编译器直接选用它,根本不会进入第二阶段去考虑「把A转换成vector
对疑问的解答
你问“是否是因为初始化列表构建时两种转换均可行,故选择了A到int的转换?”——答案是否定的。不是两种转换都可行所以二选一,而是列表初始化的重载决议规则优先在第一阶段匹配初始化列表构造函数,这条路径可行的情况下,直接跳过了第二阶段的其他可能。如果想让编译器选择A到vectorstd::vector<int> b(add());,此时会直接匹配vector的移动构造函数,触发A到vector
内容的提问来源于stack exchange,提问作者user122049
相关产品推荐
相关产品推荐

