从enable_if中的依赖类中获取true_type/false_type typedef的布尔值

Ant*_*eru 4 c++ templates metaprogramming

我有课

template <typename T>
struct Trait { typedef std::false_type IsGood; };

template <>
struct Trait<int> { typedef std::true_type IsGood; };
Run Code Online (Sandbox Code Playgroud)

像这样的调用无法在 MSVC 2010 上编译

template <typename T, typename Enable = void> class Foo;

template <typename T>
class Foo <T, std::enable_if<typename Trait<T>::IsGood::value>::type>
{};

// This fails as well
template <typename T>
class Foo <T, typename std::enable_if<Trait<T>::IsGood::value>::type>
{};

// And this fails horribly
template <typename T>
class Foo <T, typename std::enable_if<typename Trait<T>::IsGood::value>::type>
{};
Run Code Online (Sandbox Code Playgroud)

尽管

template <typename T>
class Foo <T, typename std::enable_if<std::is_same<std::true_type, 
    typename Trait<T>::IsGood>::value>::type>
{};
Run Code Online (Sandbox Code Playgroud)

有效——为什么?

错误信息是:

main.cpp(12): error C2039: 'type' : is not a member of 'std::tr1::enable_if<_Test>'
          with
          [
              _Test=false
          ]
main.cpp(12): error C2146: syntax error : missing ',' before identifier 'type'
main.cpp(12): error C2065: 'type' : undeclared identifier
main.cpp(13): error C2976: 'Foo' : too few template arguments
Run Code Online (Sandbox Code Playgroud)

Naw*_*waz 5

你用typename错地方了。这是对的:

template <typename T>
class Foo <T, typename std::enable_if<Trait<T>::IsGood::value>::type>
{};        // ^^^^^^^ here should be typename
Run Code Online (Sandbox Code Playgroud)

现在它可以正常编译: http: //ideone.com/0SwO9

但你使用的typename是:

template <typename T>
class Foo <T, std::enable_if<typename  Trait<T>::IsGood::value>::type>
{};                        //^^^^^^^ wrong place
Run Code Online (Sandbox Code Playgroud)

Trait<T>::IsGood::value不是类型,所以不能typename对其进行应用。

GCC错误信息非常清楚:

prog.cpp:12:62: 错误:“template<bool <anonymous>, class _Tp> struct std::enable_if”的模板参数列表中参数 1 的类型/值不匹配

看看你自己: http: //ideone.com/9ujJv