如果我有一个带模板方法的模板基类:
template <typename T>
class S
{
public:
template <typename U>
void f(U p, typename enable_if<is_same<T, U> >::type*dummy = 0)
{
std::cout << p << std::endl;
}
};
例如,我简化了方法:只有在T == U
时才必须“存在”如果A是这个类:
class A : public S<int> {};
然后我有我想要的东西:
int i = 1;
A a;
a.f(i);
编译,但
double d = 2.0;
a.f(d);
无法编译:错误:没有匹配函数来调用'A :: f(double&amp;)' 这是预期的行为。
现在让我们继承S<double>
:
class A : public S<int>, public S<double> {};
然后以下代码无法编译:
int i = 1;
A a;
a.f(i);
error: request for member ‘f’ is ambiguous error: candidates are: template<class U> void S::f(U, typename boost::enable_if<boost::is_same<T, U>, void>::type*) [with U = U, T = double] error: template<class U> void S::f(U, typename boost::enable_if<boost::is_same<T, U>, void>::type*) [with U = U, T = int]
我预计不存在歧义:f<int>
仅适用于S<int>
在编译器错误中,我们可以注意到编译这段代码时T是已知的,而不是U(U = U)。
任何解释或“解决方法”?
答案 0 :(得分:4)
试试这个:
a.S<int>::f(i);
...或者将函数注入A
,例如
class A : public S<int>, public S<double>
{
public:
using S<int>::f;
using S<double>::f;
};
答案 1 :(得分:0)
你说得对,它只存在于S中,但却存在两次。每种类型一次,int和double。因此,在您的情况下,您需要准确指定要调用的函数。 Nim的解决方案就是这样。
答案 2 :(得分:0)
其他人提供了很好的解决方法,但我想回答你的其他问题
我预计不存在歧义:
f<int>
仅适用于S<int>
。
您说a.f(i)
因此首先需要在f
中查找名称A
。它找到两个f
。在S<int>
和S<double>
。在名称查询时,它还不知道它以后只能选择S<int>::f
作为胜利者,因为S<double>::f
将被SFINAE抛弃。名称查找和重载决策以及模板参数推断的明确分离不允许这种混合。