假設我有這個可變參數的基類模板:C++ 11:消除歧義類成員在多重繼承
template <typename ... Types>
class Base
{
public:
// The member foo() can only be called when its template
// parameter is contained within the Types ... pack.
template <typename T>
typename std::enable_if<Contains<T, Types ...>::value>::type
foo() {
std::cout << "Base::foo()\n";
}
};
其模板的參數相匹配的至少一個時,foo()
構件只能被稱爲的Base
參數(Contains
執行在底部列出在此篇):
Base<int, char>().foo<int>(); // fine
Base<int, char>().foo<void>(); // error
現在我定義了一個派生類從基地繼承兩次,使用非重疊組類型:
struct Derived: public Base<int, char>,
public Base<double, void>
{};
我希望例如當調用該
Derived().foo<int>();
,編譯器會找出使用哪個基類,因爲它是SFINAE'd出不包含int
的一個。然而,GCC 4.9和Clang 3.5都抱怨模糊的電話。然後
我的問題是雙重的:
- 爲什麼不能編譯器解決這種不確定性(一般利益)?
- 我能做些什麼來完成這項工作,而無需編寫
Derived().Base<int, char>::foo<int>();
? 編輯: GuyGreer告訴我,當我添加兩個使用聲明時,調用是消歧的。但是,由於我爲用戶提供了繼承的基類,因此這不是一個理想的解決方案。如果可能的話,我不希望我的用戶不得不將這些聲明(對於大型類型列表可能非常冗長和重複)添加到它們的派生類中。
的Contains
實現:
template <typename T, typename ... Pack>
struct Contains;
template <typename T>
struct Contains<T>: public std::false_type
{};
template <typename T, typename ... Pack>
struct Contains<T, T, Pack ...>: public std::true_type
{};
template <typename T, typename U, typename ... Pack>
struct Contains<T, U, Pack ...>: public Contains<T, Pack...>
{};
這是一般規律的體現,從不同範圍的名稱不使用C超載++。 – 2015-02-05 16:25:23