## Mengapa Pewarisan Berbilang dengan Kelas Asas Templat Menyebabkan Kekaburan dalam Penyelesaian Fungsi Ahli?

Barbara Streisand
Lepaskan: 2024-10-25 04:58:02
asal
529 orang telah melayarinya

## Why Does Multiple Inheritance with Template Base Classes Cause Ambiguity in Member Function Resolution?

Kekaburan dalam Menyahkambiguasi Berbilang Warisan

Apabila berurusan dengan berbilang warisan menggunakan kelas asas templat, kemungkinan isu timbul mengenai penyelesaian fungsi ahli yang tidak jelas. Pertimbangkan senario 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

Di sini, fungsi foo() hanya boleh dipanggil apabila parameter templat sepadan dengan salah satu jenis dalam pek Jenis. Sekarang, jika kelas terbitan mewarisi daripada berbilang kelas asas dengan set jenis tidak bertindih, pengkompil mungkin menghadapi kesamaran semasa menyelesaikan panggilan foo().

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

Dalam kes ini, panggilan Derived(). foo() sebaiknya memanggil fungsi ahli foo() daripada Base. Walau bagaimanapun, kedua-dua GCC dan Clang melaporkan kekaburan.

Mengapa Pengkompil Tidak Dapat Menyelesaikan Kekaburan

Ralat kompilasi timbul kerana peraturan gabungan untuk carian fungsi ahli. Mengikut piawaian C, jika fungsi ahli tidak diisytiharkan dalam kelas terbitan itu sendiri, proses carian mencari kelas asas secara bergilir-gilir. Walau bagaimanapun, jika set pengisytiharan dalam kelas asas berbeza, cantuman menjadi samar-samar.

Dalam senario yang diberikan, kelas terbitan Derived tidak mengisytiharkan foo() secara eksplisit, jadi pengkompil mesti menggabungkan set carian daripada dua kelas asas. Memandangkan kelas asas mengandungi set pengisytiharan yang berbeza untuk foo(), gabungan menghasilkan kesamaran.

Penyelesaian

Untuk menyelesaikan kekaburan ini, satu pilihan ialah menggunakan menggunakan pengisytiharan dalam kelas terbitan untuk mengimport secara eksplisit fungsi ahli yang dikehendaki. Walau bagaimanapun, ini memerlukan pengguna untuk menambah pengisytiharan ini, yang boleh menjadi kata-kata dan tidak praktikal untuk senarai jenis besar.

<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

Sebagai alternatif, seseorang boleh menggunakan kelas pembantu yang mengumpul dan menggabungkan fungsi ahli daripada semua kelas asas , membenarkan kelas terbitan mengaksesnya secara langsung.

<code class="cpp">template <typename... Bases>
struct BaseCollector : Bases...
{
  using Bases::foo...;
};

struct Derived : BaseCollector<Base<int, char>, Base<double, void>>
{};</code>
Salin selepas log masuk

Dengan pendekatan ini, pengguna tidak perlu menambah sebarang pengisytiharan tambahan untuk menyelesaikan kekaburan. Kelas BaseCollector menggabungkan set pengisytiharan daripada semua kelas asas dengan berkesan, menjadikan fungsi foo() tersedia kepada kelas terbitan tanpa kesamaran.

Atas ialah kandungan terperinci ## Mengapa Pewarisan Berbilang dengan Kelas Asas Templat Menyebabkan Kekaburan dalam Penyelesaian Fungsi Ahli?. 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!