Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Mengapa Kesamaran Pewarisan Berbilang Berlaku dalam C Apabila Memanggil Fungsi Ahli Templat Variadik?

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

Susan Sarandon
Susan Sarandonasal
2024-10-25 01:50:30830semak imbas

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"; }
};

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>

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>

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>

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!

Kenyataan:
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