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;
}
tidak ada yang istimewa
sumber

Jawaban:

14

Gunakan inisialisasi langsung:

Class<std::string> b("abc");
Dranjohn
sumber
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
JeJo
sumber
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.
Evg
sumber
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 .

penghijauan
sumber