为何C++会选择基础类型重载而非匹配度更高的初始化列表?
C++中为何编译器选择基础类型重载而非初始化列表匹配?
示例代码如下:
#include <vector> void foo([[maybe_unused]] int i) {} void foo([[maybe_unused]] const std::vector<int>& v) {} int main() { foo(0); foo({1,2,3}); foo({0}); // 调用foo(int)并发出警告,而非看似更匹配的foo(vector),原因是什么? }
编译后会触发如下警告:
<source>:10:9: warning: braces around scalar initializer [-Wbraced-scalar-init] foo({0}); // calls foo(int) and issues a warning, ^~~
原因解析
这是由C++重载决议的优先级规则决定的:
- 当调用
foo({0})时,编译器会优先评估匹配优先级:对于接收int的重载,{0}可以直接完成标量类型的列表初始化,这属于标准转换序列,在重载匹配中的优先级更高。 - 而对于接收
const std::vector<int>&的重载,需要先通过std::vector的列表构造函数创建临时对象,这属于用户定义转换序列,其匹配优先级低于标准转换序列。
即便用大括号初始化标量类型会触发代码风格警告,但重载决议的优先级规则是硬性的,编译器会优先选择优先级更高的重载,警告仅作为风格提示,不影响最终的决议结果。
内容的提问来源于stack exchange,提问作者Oliver Schönrock
相关产品推荐
相关产品推荐

