C++隐式转换为何选择int构造函数而非string构造函数?
C++隐式转换疑问:为何
const char*会匹配int构造函数? 测试代码
#include <iostream> #include <format> class Entity { public: int age; std::string name; Entity(const std::string& name) : name(name), age(-1) {} Entity(const int age) : age(age), name("Unknown") {} }; void printEntity(const Entity& e) { std::cout << std::format("Age: {}, Name: {}\n", e.age, e.name); } int main() { Entity a = 35; printEntity(a); Entity b = "mr someone"; printEntity(b); printEntity(23); }
编译错误与异常输出
使用g++ xplicit.cpp --std=c++23编译时,报错如下:
xplicit.cpp: In function ‘int main()’: xplicit.cpp:25:16: error: invalid conversion from ‘const char*’ to ‘int’ [-fpermissive] 25 | Entity b = "mr someone"; | ^~~~~~~~~~~ | | | const char*
添加-fpermissive参数后编译通过,但输出异常:
Age: 35, Name: Unknown Age: -1374514851, Name: Unknown // entity b Age: 23, Name: Unknown
问题解析
编译器优先尝试将const char*转为int而非std::string,核心原因是C++重载决议的转换优先级规则:
const char*转int属于标准转换序列(尽管这是不安全的指针转数值操作,但仍属于C++标准定义的转换类型);const char*转std::string需要调用std::string的构造函数,属于用户定义的转换序列。
在重载决议时,标准转换序列的优先级高于用户定义的转换序列,因此编译器会优先匹配接受int的构造函数,而非接受std::string的版本。
添加-fpermissive参数后,编译器放宽了对不安全隐式转换的限制,直接将字符串字面量的指针地址强转为int值赋值给age,因此输出的age是无意义的垃圾值,同时调用int版本构造函数将name设为Unknown。
解决方法
要让Entity b = "mr someone"正常工作,有两种常见方案:
- 新增一个接受
const char*的构造函数,避免二次转换:Entity(const char* name) : name(name), age(-1) {} - 显式将字符串字面量转换为
std::string:Entity b = std::string("mr someone");
内容的提问来源于stack exchange,提问作者Fnr
相关产品推荐
相关产品推荐

