Bagaimana cara memanggil konstruktor yang tepat dari tipe templat?


21

Dalam kode berikut, bagaimana saya bisa membuat baris komentar bekerja dengan cara yang sama dengan baris di atasnya?

Saya ingin membuatnya menjadi kode generik, yang memanggil konstruktor template yang sesuai 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;
}

Jawaban:


14

Gunakan inisialisasi langsung:

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

17

Gunakan bracing-init-list (atau seragam-inisiasi) untuk menginisialisasi instance Class.

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

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

adalah inisialisasi salin . Tidak berfungsi karena akan melibatkan dua konversi yang ditentukan pengguna:

  • dari const char*ke std::string,
  • dari std::stringke Class<std::string>.

Tetapi paling banyak orang diizinkan.

Ketika Anda menulis

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

Anda menggunakan inisialisasi langsung . Ini berfungsi karena sekarang hanya satu konversi yang ditentukan pengguna yang digunakan:

  • dari const char*ke std::string.

0

Jika Anda bisa mengubah Anda Class, Anda bisa menambahkan konstruktor konversi templated. Maka Anda dapat mengkompilasi baris komentar seperti yang ditulis dalam contoh Anda. Perhatikan, bahwa pada umumnya tidak disarankan untuk menggunakan konversi tersirat tanpa alasan yang layak karena mereka dapat mengakibatkan bug yang sulit ditemukan (lihat Pedoman Inti 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;
}

Jika Anda bisa menggunakan C ++ 14, Anda bisa menggunakan std::literals::string_literals::operator""sdan menghapus konstruktor konversi. Kemudian, baris Anda akan terlihat seperti ini:

using namespace std::literals;

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

Kode langsung di sini .

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.