问题
I have a class template Bird
with a Boolean template parameter can_fly
. Depending on that value, I want to enable a member function with the signature void fly();
.
This is my code:
#include <type_traits>
template<bool can_fly>
class Bird {
public:
template<typename void_t = typename std::enable_if<can_fly>::type>
void_t fly() { /* ... */ }
};
int main() {
Bird<true> flyingBird;
flyingBird.fly();
Bird<false> flightlessBird;
return 0;
}
This code compiles fine in Visual Studio 2015, but GCC complains that there is "no type named 'type' in 'struct std::enable_if'" in the third line of main
.
I thought the fact that there is no ::type
in the false
case was the entire point of SFINAE. Can somebody explain to me what I did wrong and what the correct approach is?
回答1:
As mentioned in this answer:
enable_if works because the substitution of a template argument resulted in an error, and so that substitution is dropped from the overload resolution set and only other viable overloads are considered by the compiler.
In your case there is no substitution because can_fly
is known at the moment of instantiation. You can create a dummy default bool
template parameter to make SFINAE work properly:
template<bool can_fly>
class Bird {
public:
template<bool X = can_fly, typename = typename std::enable_if<X>::type>
void fly() { /* ... */ }
};
wandbox example
来源:https://stackoverflow.com/questions/41091480/how-to-use-sfinae-with-nullary-member-function