Вопрос

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>

Это было полезно?

Решение

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>>
//            ^^^^^^^^^^^^^^^^
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top