enable_if:模板库的模板化方法的情况多次继承

时间:2011-10-20 14:38:46

标签: c++ templates boost enable-if

如果我有一个带模板方法的模板基类:

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)。

任何解释或“解决方法”?

3 个答案:

答案 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抛弃。名称查找和重载决策以及模板参数推断的明确分离不允许这种混合。