【问题标题】:Why doesn't SFINAE (enable_if) work for member functions of a class template?为什么 SFINAE (enable_if) 不适用于类模板的成员函数?
【发布时间】:2020-10-03 15:10:06
【问题描述】:
#include <type_traits>

struct A{};
struct B{};

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()
    {}
};

错误信息:

14:5: error: 'typename std::enable_if<std::is_same<T, B>::value>::type Foo<T>::bar()' cannot be overloaded 10:5: 
error: with 'typename std::enable_if<std::is_same<T, A>::value>::type Foo<T>::bar()'

来源cpp.sh。我认为typename std::enable_if&lt;std::is_same&lt;T,?&gt;::value&gt;::type 不能同时有效。

编辑

这里是我根据@KerrekSB 的回答进行的编辑——SFINAE 仅适用于推导的模板参数

#include <type_traits>

struct A{};
struct B{};

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()
    {
    }
};

int main()
{
};

【问题讨论】:

    标签: c++ c++11 sfinae enable-if


    【解决方案1】:

    SFINAE 仅适用于 deduced 模板参数,即函数模板。在您的情况下,两个模板都是无条件实例化的,并且实例化失败。

    以下变体有效:

    struct Foo
    {
        template <typename T>
        typename std::enable_if<std::is_same<T, A>::value>::type bar(T) {}
    
        // ... (further similar overloads) ...
    };
    

    现在Foo()(x) 导致最多实例化一个重载,因为参数替换在所有其他重载中都失败了。

    如果您想坚持原来的结构,请使用显式类模板特化:

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

    【讨论】:

    • SFINAE 仅适用于推导的模板参数 ...这是关键!!!!!!谢谢一堆@Kerrek。顺便说一句,我原来的帖子是 MWE。
    • @Olumide:是的,只有因扣减导致的替换失败不是错误。明确请求的替换确实会作为硬错误失败。 (对于这种情况,一个 MFE 就足够了!)
    • 有没有办法像这样重载构造函数?
    猜你喜欢
    • 2012-01-22
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    • 2012-02-23
    • 1970-01-01
    相关资源
    最近更新 更多