为何调用my_function({})会选择const char*重载而非std::string?
空初始化列表触发
const char*重载的原因解析 当你调用my_function({})时,编译器选择const char*重载而非std::string版本,核心原因是C++重载决议的转换序列优先级规则:
1. 两种重载的匹配路径
- 对于
const char*重载:空初始化列表{}可以隐式转换为std::nullptr_t,而std::nullptr_t又能直接标准转换为const char*——这属于标准转换序列,优先级更高。 - 对于
std::string重载(无论是引用还是值传递):要匹配这个重载,需要从空初始化列表构造出一个std::string对象,这依赖于std::string的默认构造函数或initializer_list<char>构造函数,属于用户定义转换序列,优先级低于标准转换序列。
编译器在重载决议时会优先选择转换序列优先级更高的重载,因此最终选中了const char*版本,传入nullptr。
2. 为什么改值传递也没用?
即使把std::string重载改成值传递,本质还是需要通过用户定义转换从{}构造std::string对象,转换序列的优先级并没有变化,所以编译器依然会选择const char*重载。
3. 崩溃的原因
如果后续代码中对传入的const char*指针进行了解引用(比如尝试打印指针指向的内容),而指针是nullptr,就会触发未定义行为,直接导致程序崩溃。
解决方法
如果你希望my_function({})匹配std::string版本,可以通过以下方式处理:
- 显式构造
std::string对象:my_function(std::string{}) - 禁用
nullptr到const char*的匹配:新增一个被删除的重载,阻断空列表到const char*的转换:
这样编译器会因为void my_function(std::nullptr_t) = delete;nullptr_t重载被删除,转而选择std::string版本。
内容的提问来源于stack exchange,提问作者Rob L
相关产品推荐
相关产品推荐

