首頁 > 後端開發 > C++ > 主體

## 為什麼模板基底類別的多重繼承會導致成員函數解析不明確?

Barbara Streisand
發布: 2024-10-25 04:58:02
原創
529 人瀏覽過

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

消除多重繼承的歧義

使用模板基類處理多重繼承時,會出現關於不明確成員函數解析的潛在問題。考慮以下場景:

<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";
  }
};
登入後複製

這裡,只有當模板參數與類型包中的其中一種類型相符時,函數 foo() 才可呼叫。現在,如果派生類別繼承自具有不重疊類型集的多個基類,則編譯器在解析 foo() 呼叫時可能會遇到歧義。

<code class="cpp">struct Derived: public Base<int, char>,
                public Base<double, void>
{};</code>
登入後複製

在這種情況下,呼叫 Derived()。 foo() 理想情況下會從 Base 呼叫 foo() 成員函數。然而,GCC 和 Clang 都報告了歧義。

為什麼編譯器無法解決歧義

由於成員函數查找的合併規則而出現編譯錯誤。根據C標準,如果衍生類別本身沒有宣告成員函數,則尋找過程依序搜尋基底類別。但是,如果基底類別中的聲明集不同,合併就會變得不明確。

在給定的場景中,衍生類別 Derived 沒有明確聲明 foo(),因此編譯器必須合併來自兩個基底類別。由於基底類別包含 foo() 的不同聲明集,因此合併會導致歧義。

解決方案

要解決此歧義,一種選擇是使用 using 聲明在派生類別中明確導入所需的成員函數。但是,這需要用戶添加這些聲明,這對於大型類型清單來說可能很冗長且不切實際。

<code class="cpp">struct Derived: public Base<int, char>,
                public Base<double, void>
{
    using Base<int, char>::foo;
    using Base<double, void>::foo;
};</code>
登入後複製

或者,可以使用一個輔助類別來收集和合併來自所有基底類別的成員函數,允許衍生類別直接存取它們。

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

struct Derived : BaseCollector<Base<int, char>, Base<double, void>>
{};</code>
登入後複製

使用這種方法,使用者不需要添加任何額外的聲明來解決歧義。 BaseCollector 類別有效地合併了所有基底類別的宣告集,使 foo() 函數可用於衍生類別而不會產生歧義。

以上是## 為什麼模板基底類別的多重繼承會導致成員函數解析不明確?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!