Mengapa Kesamaran Pewarisan Berbilang Berlaku dalam C Apabila Memanggil Fungsi Ahli Templat Variadik?

Susan Sarandon
Lepaskan: 2024-10-25 01:50:30
asal
829 orang telah melayarinya

Why Does Multiple Inheritance Ambiguity Occur in C   When Calling a Variadic Template Member Function?

Nyahkekaburan Ahli Kelas Warisan Berbilang

Pertimbangkan templat kelas asas variadik berikut:

<code class="cpp">template <typename... Types>
class Base {
public:
    template <typename T>
    typename std::enable_if<Contains<T, Types...>::value>::type
    foo() { std::cout << "Base::foo()\n"; }
};
Salin selepas log masuk

The foo() ahli hanya boleh dipanggil dengan parameter templat yang sepadan dengan salah satu jenis dalam pek Jenis. Sekarang, mari kita takrifkan kelas terbitan dengan jenis asas yang tidak bertindih:

<code class="cpp">struct Derived : public Base<int, char>, public Base<double, void> {};</code>
Salin selepas log masuk

Panggilan Derived().foo() harus diselesaikan secara intuitif ke Base kelas asas. Walau bagaimanapun, pengkompil mengadu tentang kekaburan.

Mengapa Pengkompil Tidak Dapat Menyelesaikan Kekaburan:

Peraturan gabungan untuk carian ahli [class.member.lookup] menyatakan bahawa apabila kelas terbitan mempunyai set pengisytiharan kosong (tiada ahli), set carian daripada semua kelas asas mesti digabungkan. Dalam kes kami, kelas asas mempunyai set pengisytiharan yang berbeza, jadi penggabungan gagal.

Penyelesaian:

Untuk mengelakkan kekaburan ini, kita boleh menambah menggunakan pengisytiharan kepada terbitan kelas:

<code class="cpp">struct Derived : public Base<int, char>, public Base<double, void> {
    using Base<int, char>::foo;
    using Base<double, void>::foo;
};</code>
Salin selepas log masuk

Dengan memperkenalkan lebihan foo dalam kelas terbitan, kami secara berkesan memintas peraturan gabungan.

Menggunakan Kelas Pengumpul:

Sebagai alternatif, kita boleh menggunakan kelas templat untuk mengagregatkan pengisytiharan penggunaan daripada semua kelas asas:

<code class="cpp">template <typename... Bases>
struct BaseCollector;

template <typename Base, typename... Bases>
struct BaseCollector<Base, Bases...> : Base, BaseCollector<Bases...> {
    using Base::foo;
    using BaseCollector<Bases...>::foo;
};

struct Derived : BaseCollector<Base2<int>, Base2<std::string>> {};</code>
Salin selepas log masuk

Pendekatan ini lebih cekap untuk disusun dalam C 17, kerana ia membenarkan pengembangan pek menggunakan pengisytiharan.

Atas ialah kandungan terperinci Mengapa Kesamaran Pewarisan Berbilang Berlaku dalam C Apabila Memanggil Fungsi Ahli Templat Variadik?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!