Cannot get SFINAE to work.

This is my first attempt at SFINAE:

#include <type_traits> #include <iostream> struct C1 { using T = int; }; struct C2 { using T = void; }; // For classes that declare T = int template <class C> void f(C &c, std::enable_if<!std::is_same<typename C::T, void>::value, int>::type = 0) { std::cout << "With T" << std::endl; } // For classes that declare T = void template <class C> void f(C &c, std::enable_if<std::is_same<typename C::T, void>::value, int>::type = 0) { std::cout << "Without T" << std::endl; } int main() { C1 c1; f(c1); // With T C2 c2; f(c2); // Without T return 0; } 

The compiler (gcc 4.8.2) complains:

 'std::enable_if<!(std::is_same<typename C::T, void>::value), int>::type' is not a type 

What am I doing wrong?

+5
source share
1 answer

For this you need a pair of typename :

 // For classes that declare T = int template <class C> void f(C &c, typename std::enable_if<!std::is_same<typename C::T, void>::value, int>::type = 0) { std::cout << "With T" << std::endl; } // For classes that declare T = void template <class C> void f(C &c, typename std::enable_if<std::is_same<typename C::T, void>::value, int>::type = 0) { std::cout << "Without T" << std::endl; } 

Or, if your compiler supports C ++ 14, you can use std::enable_if_t :

 // For classes that declare T = int template <class C> void f(C &c, std::enable_if_t<!std::is_same<typename C::T, void>::value, int> = 0) { std::cout << "With T" << std::endl; } // For classes that declare T = void template <class C> void f(C &c, std::enable_if_t<std::is_same<typename C::T, void>::value, int> = 0) { std::cout << "Without T" << std::endl; } 
+7
source

Source: https://habr.com/ru/post/1237856/


All Articles