2

Try to understand SFINAE.

template <class T, class T1 = void>
struct foo
{
    static constexpr char* a = "primary definition\n";
};

struct A
{
};

template <class T>
struct foo<T, std::enable_if<std::is_same<T, A>::value>::type>
{
    static constexpr char* a = "secondary definition\n";
};

Compiler gcc-4.8.1 gives an error

error: type/value mismatch at argument 2 in template parameter list for ‘template struct foo’ struct foo::value>::type>

Bikineev
  • 1,685
  • 15
  • 20

1 Answers1

2

C++11 Standard: 14.6/3

When a qualified-id is intended to refer to a type that is not a member of the current instantiation (14.6.2.1) and its nested-name-specifier refers to a dependent type, it shall be prefixed by the keyword typename forming a typename-specifier.

T is a dependent type, so the typename keyword is required:

struct foo<T, typename std::enable_if<std::is_same<T, A>::value>::type>
//            ^^^^^^^^

There's also a helper template provided in C++14 that is an alias returning the type:

struct foo<T, std::enable_if_t<std::is_same<T, A>::value>>
//            ^^^^^^^^^^^^^^^^
Community
  • 1
  • 1
David G
  • 94,763
  • 41
  • 167
  • 253