我正试图在CObj
函数中按如下方式复制初始化我的main()
类:
#include <string>
#include <iostream>
class CObj
{
public:
CObj(std::string const& str) : m_str(str) { std::cout << "constructor" << std::endl; }
~CObj() { std::cout << "destructor" << std::endl; }
private:
std::string m_str;
};
int main()
{
CObj obj = "hello";
std::cout << "done" << std::endl;
}
但是,尽管CObj obj = "hello"
可以从std::string
隐式构造,但char const*
行无法编译。根据我在这里的理解,这应该工作。有什么理由不呢?如果我这样做有效:
CObj obj = std::string("hello");
答案 0 :(得分:4)
文字"Hello"
的类型为const char[6]
:为了调用您的构造函数,需要进行两次转换:一次转换为std::string
,另一次转换为CObj
。
但是,在进行隐式转换时,C ++只允许一个用户定义的转换:
C ++标准部分§12.3/ 4 [class.conv]
类对象的类型转换可以由构造函数和转换函数指定。这些转换称为用户定义的转换,用于隐式类型转换
[...]
最多一个用户定义的转换(构造函数或转换函数)隐式应用于单个值。
这就是为什么这样做的原因:
CObj obj = std::string("hello");
或者这个:
CObj obj("hello");
或者您可以提供接受const char*
的构造函数:
CObj(const char* cstr) : m_str(cstr) { ... }
我总是建议制作这样的构造函数explicit
以避免不必要的隐式转换,除非它真的给类的用户带来了一些东西。
答案 1 :(得分:2)
在实例化对象时,您最多只能进行一次用户定义的转换(即char[6]
- &gt; std::string
和std::string
- &gt; CObj
是一次转换太多了。)
修复:
int main()
{
using namespace std::literals::string_literals; // this is necessary
// for the literal conversion
CObj obj = "hello"s; // note the extra "s", (which constructs a std::string)
std::cout << "done" << std::endl;
}