Question

I'm trying to partially specialize a trait for arrays of non-chars:

template<typename T>
struct is_container : std::false_type {};

template<typename T, unsigned N>
struct is_container<T[N]>
: std::enable_if<!std::is_same<T, char>::value, std::true_type>::type {};

Visual Studio 2010 gives me a C2039 (type is no element of enable_if...). However, shouldn't SFINAE just bottom out here instead of giving a compiler error? Or does SFINAE not apply in this case?

Of course I could just separate the specializations for non-char and char:

template<typename T>
struct is_container : std::false_type {};

template<typename T, unsigned N>
struct is_container<T[N]> : std::true_type {};

template<unsigned N>
struct is_container<char[N]> : std::false_type {};

But I would really like to know why SFINAE doesn't work in this particular case.

Was it helpful?

Solution

Check the topic '3.1 Enabling template class specializations' at http://www.boost.org/doc/libs/1_47_0/libs/utility/enable_if.html

Edit: in case boost.org link dies...

3.1 Enabling template class specializations Class template specializations can be enabled or disabled with enable_if. One extra template parameter needs to be added for the enabler expressions. This parameter has the default value void. For example:

template <class T, class Enable = void> 
class A { ... };

template <class T>
class A<T, typename enable_if<is_integral<T> >::type> { ... };

template <class T>
class A<T, typename enable_if<is_float<T> >::type> { ... };

Instantiating A with any integral type matches the first specialization, whereas any floating point type matches the second one. All other types match the primary template. The condition can be any compile-time boolean expression that depends on the template arguments of the class. Note that again, the second argument to enable_if is not needed; the default (void) is the correct value.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top