[英]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.