简体   繁体   English

为什么 SFINAE (enable_if) 不适用于类模板的成员函数?

[英]Why doesn't SFINAE (enable_if) work for member functions of a class template?

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

Error message:错误信息:

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()'

Source on cpp.sh .来源在cpp.sh I thought both typename std::enable_if<std::is_same<T,?>::value>::type could not be valid at the same time.我认为typename std::enable_if<std::is_same<T,?>::value>::type不能同时有效。

Edit编辑

For posterity here is my edit based on @KerrekSB's answer -- SFINAE only works for deduced template arguments对于后代,这里是我根据@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()
{
};

SFINAE only works for deduced template arguments, ie for function templates. SFINAE 仅适用于推导的模板参数,即函数模板。 In your case, both templates are unconditionally instantiated, and the instantiation fails.在您的情况下,两个模板都被无条件实例化,并且实例化失败。

The following variant works:以下变体有效:

struct Foo
{
    template <typename T>
    typename std::enable_if<std::is_same<T, A>::value>::type bar(T) {}

    // ... (further similar overloads) ...
};

Now Foo()(x) causes at most one of the overloads to be instantiated, since argument substitution fails in all the other ones.现在Foo()(x)导致最多一个重载被实例化,因为参数替换在所有其他重载中失败。

If you want to stick with your original structure, use explicit class template specialization:如果您想坚持使用原始结构,请使用显式类模板特化:

template <typename> struct Foo;

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么 void_t 在 SFINAE 中不起作用但 enable_if 可以 - Why void_t doesnt work in SFINAE but enable_if does 为什么这个简单的enable_if不起作用? - Why doesn't this simple enable_if work? enable_if、SFINAE 和模板参数? - enable_if, SFINAE and template parameters? enable_if on类模板的成员模板函数 - enable_if on member template function of class template 当一个条件分支从基础 class 继承时,为什么此 SFINAE 不能与 enable_if 一起使用? - Why does this SFINAE not work with enable_if when one conditional branch is inherited from the base class? 如何使用enable_if根据类的模板参数启用成员函数 - How to use enable_if to enable member functions based on template parameter of class 当 enable_if&lt;&gt; = void 不起作用时,为什么 enable_if&lt;&gt;* = nullptr 起作用? - Why does enable_if<>* = nullptr work when enable_if<> = void doesn't? 为什么在尝试 class 成员指针时 SFINAE 技巧不适用于非类类型? - Why SFINAE trick doesn't work for non-class type when tried for class member pointer? 为什么带有通用引用的过载(使用enable_if)不起作用? - Why doesn't the overload (using enable_if) with universal reference work? 可变参数模板专业化,std :: enable_if,SFINAE - Variadic template specialization, std::enable_if, SFINAE
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM