问题
Why is class A
compiling and class B
not compiling, where the compiler complains about having two declarations, are not both relying on SFINAE?
Both should actually use template type deduction when using foo
?
So the question really is, whats the subtle different in these two version
and why is class A
successfully using sfinae...?
- Class A uses a value-defaulted (zero) annonymous (not necessary) non-type template parameter
- Class B uses a type-defaulted (with enable_if) annonymous type template parameter
The code:
template<typename T>
struct A
{
template<typename U,
typename std::enable_if<!std::is_floating_point<U>::value>::type * = nullptr
>
void foo() {}
template<typename U,
typename std::enable_if<std::is_floating_point<U>::value>::type * = nullptr
>
void foo() {}
};
template<typename T>
struct B
{
template<typename U,
typename = typename std::enable_if<!std::is_floating_point<U>::value>::type
>
void foo() {}
template<typename U,
typename = typename std::enable_if<std::is_floating_point<U>::value>::type
>
void foo() {}
};
Live code at: http://coliru.stacked-crooked.com/a/40ec5efc7ba2a47c
回答1:
§1.3.22 defines the signature of a function template:
signature
<
class member function template>
name, parameter type list (8.3.5), class of which the function is a member, cv-qualifiers (if any), ref-qualifier (if any), return type, and template parameter list
The template parameter list does not include the default arguments given. For A::foo
, the template parameters are not equivalent (a term precisely defined in §14.5.6.1). In B::foo
, they are. You're simply declaring the same function template with different default arguments - and thereby violate both §9.2/1 and §14.1/12.
This is a common problem when overloading function templates solely by a condition for enable_if
. In particular for constructors, where you can't place the enable_if
part in the return value.
回答2:
In class B
, both foo
have same signature (even if they are different default value):
template <typename U, typename Dummy>
void foo();
So the error for class B.
In class A, the type are literally different (even if they both ends to void
)
来源:https://stackoverflow.com/questions/31625914/sfinae-for-class-member-function-one-compiles-the-other-not