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.

+6
source share
1 answer

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”.

+5
source

All Articles