Làm thế nào để gọi đúng hàm tạo của kiểu mẫu?


21

Trong đoạn mã sau, làm thế nào tôi có thể làm cho dòng nhận xét hoạt động theo cách tương tự như dòng ngay phía trên của nó?

Tôi muốn làm cho nó một mã chung, gọi hàm tạo phù hợp của mẫu 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âu trả lời:


14

Sử dụng khởi tạo trực tiếp:

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

17

Sử dụng braces-init-list (hoặc bắt đầu thống nhất) để khởi tạo thể hiện của Class.

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

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

khởi tạo bản sao . Nó không hoạt động vì nó sẽ liên quan đến hai chuyển đổi do người dùng xác định:

  • từ const char*đến std::string,
  • từ std::stringđến Class<std::string>.

Nhưng nhiều nhất là một được cho phép.

Khi bạn viết

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

bạn sử dụng khởi tạo trực tiếp . Nó hoạt động vì bây giờ chỉ có một chuyển đổi do người dùng xác định được sử dụng:

  • từ const char*đến std::string.

0

Nếu bạn có thể thay đổi Class, bạn có thể thêm một hàm tạo chuyển đổi templated. Sau đó, bạn có thể biên dịch dòng nhận xét như được viết trong ví dụ của bạn. Tuy nhiên, thông thường, không nên sử dụng các chuyển đổi ngầm mà không có lý do chính đáng vì chúng có thể dẫn đến các lỗi khó phát hiện (cf Hướng dẫn cốt lõi của 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;
}

Nếu bạn có thể sử dụng C ++ 14, bạn có thể sử dụng std::literals::string_literals::operator""svà loại bỏ hàm tạo chuyển đổi. Sau đó, dòng của bạn sẽ trông như thế này:

using namespace std::literals;

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

Mã sống ở đây .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.