C++ 在复制初始化期间,std::string的隐式构造不会发生

C++ 在复制初始化期间,std::string的隐式构造不会发生,c++,C++,我正试图在main()函数中复制并初始化我的CObj类,如下所示: #include <string> #include <iostream> class CObj { public: CObj(std::string const& str) : m_str(str) { std::cout << "constructor" << std::endl; } ~CObj() { std::cout << "dest

我正试图在
main()
函数中复制并初始化我的
CObj
类,如下所示:

#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;
}
文本
“Hello”
的类型为
const char[6]
:为了调用构造函数,需要进行两次转换:一次转换为
std::string
,另一次转换为
CObj

<>但是C++在进行隐式转换时只允许一个用户定义的转换:

C++标准章节§12.3/4[类别转换]

类对象的类型转换可以由构造函数和转换函数指定。这些转换称为用户定义的转换,用于隐式类型转换

[……]

最多对单个值隐式应用一个用户定义的转换(构造函数或转换函数)


这就是为什么这样做的原因:

CObj obj = std::string("hello");
或者这个:

CObj obj("hello");
或者,您可以提供一个接受
常量char*
的构造函数:

CObj(const char* cstr) : m_str(cstr) { ... }

我总是建议将此类构造函数显式化,以避免不必要的隐式转换,除非它确实给类的用户带来了一些东西。

实例化对象时,您最多只能进行一次用户定义的转换(即
char[6]
->
std::string
std::string
->
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;
}
intmain()
{
使用命名空间std::literals::string_literals;//这是必需的
//用于文字转换
CObj obj=“hello”s;//注意额外的“s”(它构造了一个std::string)

std::cout在隐式转换序列中只能有一个用户定义的隐式转换。尝试两个:从字符串文字到
string
和从
string
CObj
“hello”是
常量字符[6],不是<代码> STD::String const和STR ,只有1个用户定义的转换允许您从C++标准(不是我)看到一个引用;我认为您应该/可以建议创建另一个构造函数,接受<代码> const char */Cube >,或者他可以写<代码> CObj obj(“hello”);< /C> >,这应该工作。
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;
}