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

时间:2014-10-13 14:00:05

标签: c++

我正试图在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");

2 个答案:

答案 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::stringstd::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;
}