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

发布于 2024-12-11 07:18:03 字数 1305 浏览 0 评论 0 原文

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

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

没有t 编译:错误:没有匹配的函数可用于调用“A::f(double&)” 这是预期的行为。

现在让 A 也继承自 S

class A : public S<int>, public S<double> {};

那么以下代码将无法编译:

int i = 1;
A a;
a.f(i);
错误:对成员“f”的请求不明确

错误:候选者是:template void S::f(U, 类型名
boost::enable_if, void>::type*) [其中 U = U, T =
双倍的]

错误:模板<类 U> void S::f(U, 类型名
boost::enable_if, void>::type*) [其中 U = U, T =
整数]

我期望没有歧义: f 仅存在于 S

在编译器错误中,我们可以注意到,当这段代码为 T 时,T 是已知的已编译,但不是 U (U = U)。

有什么解释或“解决方法”吗?

If I have a template base class with a template method :

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;
    }
};

For the example, I simplify the method : it must "exists" only if T == U

If A is this class:

class A : public S<int> {};

Then I have what I want:

int i = 1;
A a;
a.f(i);

compiles, but

double d = 2.0;
a.f(d);

doesn't compile : error: no matching function for call to ‘A::f(double&)’
It is the expected behavior.

Now let's A inherit from S<double> also :

class A : public S<int>, public S<double> {};

Then the following code doesn't compile:

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]

I expected there is no ambiguity : f<int> exists only for S<int>

In the compiler error, we can notice that T is known when this piece of code is compiled, but not U (U = U).

Any explanation or "workaround" ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

森林迷了鹿 2024-12-18 07:18:03

试试这个:

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

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

class A : public S<int>, public S<double> 
{
public:
  using S<int>::f;
  using S<double>::f;
};

Try this:

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

...or alternatively inject the function into A, e.g.

class A : public S<int>, public S<double> 
{
public:
  using S<int>::f;
  using S<double>::f;
};
£噩梦荏苒 2024-12-18 07:18:03

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

You are right it only exists in S, but two times. Once for each type, int and double. So in your case you will need to specify exactly which function you want to call. The solution from Nim works just like that.

一场春暖 2024-12-18 07:18:03

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

我希望没有歧义:f 仅适用于 S

您说的是 af(i),因此它首先需要在 A 中查找名称 f。它找到两个f。在 SS 中。在名称查找时,它还不知道稍后只能选择 S::f 作为获胜者,因为 S::f 会被 SFINAE 扔掉。名称查找和重载解析以及模板参数推导的明确分离不允许这种混合。

Others have given good workarounds, but I want to answer that other question you had

I expected there is no ambiguity : f<int> exists only for S<int>.

You said a.f(i) so it first needs to look for name f in A. It finds two fs. In S<int> and S<double>. At name lookup time, it does not know yet that it later could have only selected S<int>::f as a winner because S<double>::f would be thrown away by SFINAE. The clear separation of name lookup and overload resolution and template argument deduction does not allow such intermingling.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文