I am trying to use SFINAE to disable certain functions of a class based on some non-templated enum arguments.
The following code does NOT compile with gcc, but appears to compile and work as expected when using the msvc compiler.
#include <iostream>
#include <type_traits>
enum class B { VARIANT1, VARIANT2 };
template<B B_VAL>
struct A {
template<class = std::enable_if_t<B_VAL == B::VARIANT1>>
void func1() {
std::cout<<"VARIANT1"<<std::endl;
}
template<class = std::enable_if_t<B_VAL == B::VARIANT2>>
void func2() {
std::cout<<"VARIANT2"<<std::endl;
}
};
int main()
{
A<B::VARIANT1> a;
a.func1();
}
The expected (and msvcs) behavior is that calling a function whose enable_if_t condition equates to false results in a compile time error, or the removal of the function candidate for overload resolution if an overloaded function was present in the example. In all other cases, the code should compile normally.
gcc on the other hand tells me that it can't find a type named "type" in "struct std::enable_if<false, void>" for the enable_if_t in the template of func2, which makes perfect sense as the member named "type" is only present in enable_if if the condition equates to true. But shouldn't this be the desired behavior for the SFINAE functionality and shouldn't the compiler ignore func2, as it is never called?
I now have three questions:
As the two compilers produce different behavior, is it undefined and if yes, which parts/statements?
Is SFINAE suited to achieve my goal, or have I misunderstood its use case?
Would I be better off by using static asserts as alternative?
I am sorry if this question is a duplicate of this one, but I don't think that the answers there provided much help with my problem.