2

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

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&)' 这是预期的行为。

现在让我们 A 也继承自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)。

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

4

3 回答 3

4

试试这个:

a.S<int>::f(i);

...或者将函数注入到A中,例如

class A : public S<int>, public S<double> 
{
public:
  using S<int>::f;
  using S<double>::f;
};
于 2011-10-20T14:53:36.043 回答
0

你是对的,它只存在于 S 中,但存在两次。每种类型一次,int 和 double。因此,在您的情况下,您需要准确指定要调用的函数。Nim 的解决方案就是这样工作的。

于 2011-10-20T14:58:15.820 回答
0

其他人给出了很好的解决方法,但我想回答你的其他问题

我希望没有歧义:f<int>仅存在于S<int>.

你说a.f(i)所以它首先需要fA. 它找到两个fs。在S<int>S<double>。在名称查找时,它还不知道它后来只能被选为S<int>::f获胜者,因为它S<double>::f会被 SFINAE 扔掉。名称查找和重载解析以及模板参数推导的明确分离不允许这种混合。

于 2011-10-23T02:01:44.690 回答