首页 >后端开发 >C++ >为什么 SFINAE 在类模板中使用成员函数时会失败?

为什么 SFINAE 在类模板中使用成员函数时会失败?

Patricia Arquette
Patricia Arquette原创
2024-11-05 04:26:02347浏览

Why Does SFINAE Fail with Member Functions in Class Templates?

类模板中的成员函数 SFINAE:详细说明

在 C 世界中,SFINAE(替换失败不是错误)使通过防止编译期间的实例化错误来优化模板。然而,在处理类模板的成员函数时,SFINAE 的行为可能会出现意外。

成员函数 SFINAE 的问题

考虑以下代码:

<code class="cpp">template <typename T>
struct Foo
{
    typename std::enable_if<std::is_same<T, A>::value>::type bar();
    typename std::enable_if<std::is_same<T, B>::value>::type bar();
};</code>

与预期相反,此代码会导致错误消息。 SFINAE 没有按预期用于类模板中的成员函数。

SFINAE 和推导模板参数

问题的关键在于 SFINAE 对推导模板参数的依赖。仅当从函数调用推导模板参数时它才有效。对于成员函数,不会推导模板参数,而是显式提供。

使用推导参数的解决方案

为了解决这个问题,我们可以修改代码如下:

<code class="cpp">template<typename T>
struct Foo
{
    template<typename U = T>
    typename std::enable_if<std::is_same<U,A>::value>::type bar()
    {
    }

    template<typename U = T>
    typename std::enable_if<std::is_same<U,B>::value>::type bar()
    {
    }
};</code>

现在,当调用 Foo()(x) 时,编译器会推导出模板参数 T 并根据 x 选择正确的重载。这种方法允许 SFINAE 按预期运行。

或者:显式类模板专业化

如果类的结构至关重要且无法修改,则替代解决方案包括显式类模板特化:

<code class="cpp">template <typename> struct Foo;

template <> struct Foo<A> { void bar() {} };
template <> struct Foo<B> { void bar() {} };</code>

这里,编译器根据提供的类型确切地知道要实例化哪个特化。它不依赖 SFINAE 进行专业选择。

以上是为什么 SFINAE 在类模板中使用成员函数时会失败?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn