C++未加explicit时,拷贝初始化为何无法转换字符串字面量?
C++拷贝初始化中字符串字面量无法隐式转换的问题分析
我明确不带explicit的构造函数支持=形式的拷贝初始化(隐式转换场景),但在以下代码中执行A v = "abc";时,预期字符串字面量"abc"会先隐式转为const std::string,再调用A的构造函数,实际却报错:cannot convert from 'const char [4]' to 'A'。
原代码示例
#include <string> class A { public: A(const std::string& s = std::string()) : ps(new std::string(s)) { } A(const A& p) : ps(new std::string(*p.ps)), i(p.i) { } A& operator=(const A&); ~A() { delete ps; } private: std::string* ps; int i; }; A& A::operator=(const A& rhs) { auto newp = new std::string(*rhs.ps); delete ps; ps = newp; i = rhs.i; return *this; } int main() { A v = "abc"; // 此处报错 }
问题核心原因
C标准不允许连续两次用户定义的隐式转换。这里的预期转换链是:const char[4] → std::string(第一次隐式转换,调用std::string的非explicit构造函数)→ A(第二次隐式转换,调用A的构造函数),这条链包含两次用户定义的隐式转换,不符合C的规则,因此编译报错。
解决方案
要避免连续隐式转换,只需让字符串字面量直接成为std::string对象,消除第一次隐式转换。可以使用C++11引入的字符串字面量后缀s,步骤如下:
- 添加命名空间声明,让后缀
s生效:using namespace std::string_literals; - 将初始化语句改为
A v = "abc"s;,此时"abc"s是直接构造的std::string对象,只需一次隐式转换即可生成A对象。
修改后的main函数示例:
int main() { using namespace std::string_literals; A v = "abc"s; // 编译通过 }
内容的提问来源于stack exchange,提问作者zzzhhh
相关产品推荐
相关产品推荐

