如何调用模板类型的正确构造函数?


21

在以下代码中,如何使注释行与其上方的行一样工作?

我想将其设为通用代码,以调用合适的template构造函数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;
}

Answers:



17

使用braced-init-list(或统一初始化)来初始化的实例Class

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

13
Class<std::string> b = "abc";

复制初始化。它不起作用,因为它将涉及两个用户定义的转换:

  • const char*std::string
  • std::stringClass<std::string>

但是最多允许一个。

当你写

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

您使用直接初始化。之所以有效,是因为现在仅使用了一个用户定义的转换:

  • const char*std::string

0

如果您能够更改Class,则可以添加模板化的转换构造函数。然后,您将能够按照示例中的说明编译注释行。但是请注意,通常不建议在没有正当理由的情况下使用隐式转换,因为它们可能会导致难以发现的错误(请参阅C ++核心准则)。

#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;

现场代码在这里

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.