字符串字面量隐式转换为bool而非std::string构造函数的标准问询
为什么字符串字面量会调用bool构造函数而不是std::string构造函数?
这是个非常典型的C++重载决议问题,我来给你一步步拆解清楚:
1. 字符串字面量的本质
首先要明确:你写的"hello"是**const char[6]类型的数组**,在传递给构造函数的时候会自动退化为const char*指针。
2. 重载决议的核心规则
C++编译器在选择重载函数时,会优先挑选需要最少隐式转换、转换优先级最高的那个版本。这里的关键是区分两种转换序列的优先级:
- 标准转换序列:比如指针转bool、int转double这类语言原生支持的转换,优先级更高。
- 用户定义的转换序列:比如通过类的构造函数把
const char*转成std::string,这种涉及用户自定义逻辑的转换,优先级更低。
3. 为什么会调用bool构造函数?
对于你的代码:
- 调用
Test(bool):const char*可以隐式转换为bool(C++标准规定:任何非空指针都会转为true,空指针转为false),这属于标准转换序列。 - 调用
Test(std::string):需要通过std::string的构造函数把const char*转成std::string,这属于用户定义的转换序列。
因为标准转换序列的优先级高于用户定义的转换序列,所以编译器会优先选择Test(bool)构造函数,这就是你看到的结果。
4. 换成int/unsigned int时为什么符合预期?
C++标准有个重要规定:普通指针类型(比如const char*)不能隐式转换为整数类型(只有nullptr可以隐式转为0)。所以当你把bool换成int/unsigned int时,Test(int)这个构造函数是不可行的——编译器找不到合法的隐式转换路径把const char*转成int。
这时编译器只能选择唯一可行的Test(std::string)构造函数,所以结果就符合你的预期了。
5. 怎么让字符串字面量优先调用std::string构造函数?
如果你想避免这种意外,可以用以下两种方法:
- 显式转换:直接把字符串字面量转成
std::string再传递:Test t(std::string("hello")); - 添加精确匹配的构造函数:新增一个接受
const char*的构造函数,它会成为最优先的匹配(因为不需要任何转换),可以委托给std::string版本避免重复代码:class Test { public: Test(bool value) { std::cout << "BOOL constructor: " << value << std::endl; } Test(std::string str) { std::cout << "STRING constructor: " << str << std::endl; } Test(const char* str) : Test(std::string(str)) {} // 委托构造 };
内容的提问来源于stack exchange,提问作者Devolus
相关产品推荐
相关产品推荐

