【问题标题】:How to call the right constructor of a template type?如何调用模板类型的正确构造函数?
【发布时间】:2020-04-15 13:32:22
【问题描述】:

在下面的代码中,我怎样才能使注释行的工作方式与它上面的行相同?

我想让它成为一个通用代码,调用模板Type的合适构造函数。

#include <string>
#include <iostream>

template <typename Type>
struct Class
{
    Type data;
    Class(Type data) : data(data) { }
};

int main()
{
    Class<std::string> a = std::string("abc");
    // Class<std::string> b = "abc";
    std::cout << a.data << std::endl;
    return 0;
}

【问题讨论】:

    标签: c++ class c++11 templates initialization


    【解决方案1】:

    使用braced-init-list(或uniform-initiation)初始化Class的实例。

    Class<std::string> a{ std::string("abc") };  // works
    Class<std::string> b{ "abc" };               // also works
    

    【讨论】:

      【解决方案2】:

      使用直接初始化:

      Class<std::string> b("abc");
      

      【讨论】:

        【解决方案3】:
        Class<std::string> b = "abc";
        

        copy-initialization。它不起作用,因为它会涉及两个用户定义的转换:

        • const char*std::string
        • std::stringClass&lt;std::string&gt;

        但最多允许一个。

        当你写作时

        Class<std::string> b("abc");
        // or
        Class<std::string> b{"abc"};
        

        您使用direct-initialization。它之所以有效,是因为现在只使用了一个用户定义的转换:

        • const char*std::string

        【讨论】:

          【解决方案4】:

          如果您能够更改您的Class,您可以添加一个模板化的转换构造函数。然后你就可以编译你的例子中写的注释行。但是请注意,通常不建议在没有正当理由的情况下使用隐式转换,因为它们可能会导致难以发现的错误(参见C++ Core Guidlines)。

          #include <string>
          #include <iostream>
          
          template <typename Type>
          struct Class
          {
              Type data;
              Class(Type data) : data(data) { }
          
              template<typename Other>
              Class(Other other_data) : data(other_data) {}
          };
          
          
          int main()
          {
              Class<std::string> a = std::string("abc");
              Class<std::string> b = "abc";
              Class<std::string> c = a;
          
              std::cout << b.data << std::endl;
              return 0;
          }
          

          如果您可以使用 C++14,您可以使用 std::literals::string_literals::operator""s 并删除转换构造函数。然后,您的行将如下所示:

          using namespace std::literals;
          
          Class<std::string> b = "abc"s;
          

          直播代码here.

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-09-12
            • 2019-03-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-10-21
            • 1970-01-01
            • 2020-09-10
            相关资源
            最近更新 更多