问题
I'm trying you use std::enable_if
to conditionally choose only one out of two member function template using SFINAE with this code:
#include <iostream>
#include <type_traits>
template<typename T>
struct C {
template<typename Q = T, typename = typename std::enable_if<std::is_same<Q, int>::value>::type>
int foo() {
return 1;
}
template<typename Q = T, typename = typename std::enable_if<!std::is_same<Q, int>::value>::type>
int foo() {
return 0;
}
};
int main() {
std::cout << C<int>().foo() << std::endl; //error member function foo already defined
}
but for some reason, visual c++ keeps giving me a compiler error that foo
is already defined. Even though, it is clear that, depending on the class' template argument, only one function is well-formed. So SFINAE should remove the second one from consideration.
Any idea why this does not work?
回答1:
Try with
template<typename T>
struct C {
template<typename Q = T,
typename std::enable_if<std::is_same<Q, int>::value, bool>::type = true>
int foo() { // .............................................^^^^^^^^^^^^^^^^^^^^
return 1;
}
template<typename Q = T,
typename std::enable_if<!std::is_same<Q, int>::value, bool>::type = true>
int foo() { // ..............................................^^^^^^^^^^^^^^^^^^^^
return 0;
}
};
the point is that in your code SFINAE will enable/disable default values for template type parameter; but default values do not participate in overload resolution, so, in your case, you have two functions
template<typename, typename = void>
int foo() {
return 1;
}
template<typename, typename>
int foo() {
return 0;
}
with the same signature; so the compiler can't choose between the two and will give an error.
The code I proposed is different because in case the test of std::enable_if
is false, you don't have the type (the element on the left of the =
), not the value. Something as
// ................VVVVVV what is = true ?
template<typename, = true>
int foo() {
return 1;
}
that is a true "substitution failure" that disable the method.
来源:https://stackoverflow.com/questions/53806872/sfinae-not-working-to-conditionally-compile-member-function-template