Pertanyaan Membuat tuple-like "linked-list" tuple dengan template variadic


Saya merenungkan kemungkinan implementasi std::tuple (dan kelas template serupa dengan sejumlah variabel "anggota" yang ditentukan pada waktu kompilasi), dan saya pikir mungkin seseorang dapat membuat "tipe rekursif" yang menyerupai daftar yang ditautkan. Saya mencoba menyusun case-test berikut:

template <typename FirstType, typename... OtherTypes>
class TupleLite
{
  public:
    FirstType type_;
    TupleLite<OtherTypes...> other_types_;
};

int main()
{
  TupleLite<int,double> mytuple;
}

Kelas itu sendiri mengkompilasi tanpa kesalahan, tetapi instantiasi melemparkan kesalahan wrong number of template arguments (0, should be 1 or more). Saya percaya ini karena TupleLite<int, double> mencoba memberi contoh TupleLite<double>, yang mencoba memberi contoh TupleLite<>, yang tidak ada definisi yang valid.

Bisakah ini "kelas berukuran rekursif" diselamatkan? Saya mencoba mendefinisikan "spesialisasi tanpa argumen" TupleLite sebagai berikut:

template <>
class TupleLite {}

.... Tapi itu sepertinya tidak berhasil, meskipun g++ dan clang++ tampaknya tidak setuju pada alasannya.

Dari g++, kesalahan yang paling relevan tampaknya:

error: template specifiers not specified in declaration of ‘template<class FirstType, class ... OtherTypes> class TupleLite’
  class TupleLite
        ^
error: wrong number of template arguments (0, should be 1 or more)
 TupleLite<OtherTypes...> other_types_;
                          ^

clang++Namun, mengatakan:

error: extraneous 'template<>' in declaration of class 'TupleLite'
template <>
^
error: redefinition of 'TupleLite' as different kind of symbol
class TupleLite
      ^

5
2018-03-27 02:43


asal


Jawaban:


Definisi template utama dari TupleLite menentukan bahwa itu membutuhkan setidaknya satu argumen template, FirstType. Karena bukan itu yang ingin Anda ekspresikan, berikan defleksi template utama yang akhirnya juga menangani kotak kosong seperti ini:

template <typename...>
class TupleLite{};

Dan satu spesialisasi parsial:

template <typename FirstType, typename... OtherTypes>
class TupleLite<FirstType, OtherTypes...>
{
  public:
    FirstType type_;
    TupleLite<OtherTypes...> other_types_;
};

Demo Coliru.

EDIT: Terima kasih kepada Nikos untuk menunjukkan bahwa spesifikasi kosong tidak diperlukan dalam kasus ini.


3
2018-03-27 03:18