MSVC 2013 'type': not a member of 'std :: enable_if <false, void>
My SFINAE code using std::enable_if compiles in GCC and Clang, but not in MSVC 2013.
Code ( also available at cpp.sh )
#include <iostream> #include <type_traits> template <typename T, typename ... AdditionalInputs> typename std::enable_if<sizeof...(AdditionalInputs) == 0, void>::type CallDoDataProcessing(T var) { std::cout << sizeof...(AdditionalInputs) << " additional inputs" << std::endl; } template <typename T, typename ... AdditionalInputs> typename std::enable_if<sizeof...(AdditionalInputs) == 1, void>::type CallDoDataProcessing(T var) { std::cout << sizeof...(AdditionalInputs) << " additional inputs" << std::endl; } int main() { CallDoDataProcessing<int>(3); CallDoDataProcessing<int, int>(3); return 0; } In GCC / Clang this works fine, but in MSVC I get:
Error 1 error C2039: 'type' : is not a member of 'std::enable_if<false,void>' c:\Users\mrussell\documents\visual studio 2013\Projects\ConsoleApplication1\ConsoleApplication1\ConsoleApplication1.cpp 5 1 ConsoleApplication1 The compiled and executed output should be:
0 additional inputs 1 additional inputs I saw some similar problems on SO, but none of them had a clear answer or touched lightly.
Reading the MSVC enable_if page, this should work ...
How can I use SFINAE in MSVC2013?
UPDATE
As a note, this works in the positive case. For example, if I comment on the first function and call it, then the rest is compiled. that is, enable_if<true, void> on CallDoDataProcessing has a member of type .
However, commenting on the second function and calling it (so leaving the version where sizeof...(AdditionalInputs) == 0 does not work, the same error.
This suggests that calling sizeof...(AdditionalInputs) == 0 does not map, but I cannot understand why it will not.
Try sending tags.
template<std::size_t> struct size {}; namespace details { template <typename T, typename ... AdditionalInputs> void CallDoDataProcessing(T var, size<0>) { std::cout << sizeof...(AdditionalInputs) << ", aka 0, additional inputs" << std::endl; } template <typename T, typename ... AdditionalInputs, std::size_t N> void CallDoDataProcessing(T var, size<N>) { std::cout << sizeof...(AdditionalInputs) << " additional inputs" << std::endl; } } template <typename T, typename ... AdditionalInputs> void CallDoDataProcessing(T var) { details::CallDoDataProcessing<T, AdditionalInputs>( var, size<sizeof...(AdditionalInputs)>{} ); } SFINAE is very poorly supported by MSVC. Your code looks like a valid SFINAE. The fact that MSVC does not fit correctly is not surprising.
MSVC works much better with tagging in my experience, and I find that it even makes it sometimes easier to understand code and even error messages.
What he does not allow, he says βno, you cannot do thisβ in front of the body of the calling function, in order to force the calling function to also indicate βno, I cannot do thisβ.