Saya telah mendefinisikan:

template<class Head,class ...Tail>
struct elem{
    std::tuple<Head,Tail...> dm;
};

Saya memiliki fungsi head(), tail() dan lainnya untuk elemen kelas, tetapi mereka membuat salinan, mereka mengembalikan salinan kepala Tuple atau ekor Tuple, tetapi saya memerlukan referensi ke ekor ini-> dm.

Untuk kepala mudah, std::get<0>(this->dm) beri saya referensi.

Untuk ekornya bisa? Dengan ekor, maksud saya semua elemen setelah yang pertama.

1
Eärendil Elrond Arwen 16 Maret 2019, 15:16

1 menjawab

Jawaban Terbaik

Hal seperti itu hanya akan mungkin jika tuple<A, B, C> disimpan secara internal sebagai sesuatu yang setara dengan sel kontra:

struct __tuple_A_B_C {
    A car;
    tuple<B, C> cdr;

    A& head() { return car; }
    tuple<B, C>& tail() { return cdr; }
};

Tapi bukan itu masalahnya - yang Anda tahu adalah Anda memiliki subobjek dengan tipe A, B, dan C. Tata letaknya sama sekali tidak ditentukan - dan Anda pasti tidak tahu apakah implementasi menggunakan rekursi seperti ini untuk mengimplementasikan tuple. Mereka diizinkan, tapi saya tidak yakin ada yang melakukannya.

Yang terbaik yang dapat Anda lakukan adalah, dengan tuple<A, B, C> mengembalikan tuple<B&, C&>. Di C++17, itu tidak terlalu buruk untuk diterapkan:

template<class Head,class ...Tail>
struct elem{
    std::tuple<Head,Tail...> dm;

    auto tail() {
        return std::apply([](auto&, auto&... rest){
            return std::tie(rest...);
        }, dm);
    }
};

Tetapi jika Anda benar-benar menginginkan pendekatan seperti sel kontra rekursif ini, Anda mungkin lebih baik benar-benar menerapkan rekursi Anda sendiri sehingga Anda mendapatkan perilaku yang diinginkan:

template <class Head, class... Tail>
struct elem {
    Head head;
    elem<Tail...> tail;
};

template <class Head>
struct elem<Head> {
    Head head;
};

Tergantung pada apa yang sebenarnya Anda lakukan.

2
Barry 16 Maret 2019, 13:01