假设我有这个可变参数的基类模板: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