Search code examples
c++c++11gcccygwin

Cygwin std::enable_if parse error


I try to compile the following code under cygwin with gcc 4.9.2:

#include <type_traits>

template <template <typename...> class C, typename... Ts>
class Foo
{
    template <typename T> struct IsFoo : std::true_type {};
    template<typename T> typename std::enable_if<IsFoo<T>::value>::type bar(T v);
};

template <template <typename...> class C, typename... Ts>
template <typename T>
typename std::enable_if<Foo<C, Ts...>::IsFoo<T>::value>::type 
Foo<C, Ts...>::bar(T v)
{
    return;
}

And i got the following errors:

$ gcc -std=c++11 b.cpp
b.cpp:13:15: error: parse error in template argument list
 typename std::enable_if<Foo<C, Ts...>::IsFoo<T>::value>::type
               ^
b.cpp:13:48: error: too many template-parameter-lists
 typename std::enable_if<Foo<C, Ts...>::IsFoo<T>::value>::type
                                                ^

Strangely the code compiles under Linux (gcc 4.8.3) (http://goo.gl/uEQYB8). What could be the problem with my Cygwin environment or compiler?


Solution

  • The parse error is because:

    template <template <typename...> class C, typename... Ts>
    template <typename T>
    typename std::enable_if<Foo<C, Ts...>::IsFoo<T>::value>::type 
    Foo<C, Ts...>::bar(T v) { /**/ }
    

    should be:

    template <template <typename...> class C, typename... Ts>
    template <typename T>
    typename std::enable_if<Foo<C, Ts...>::template IsFoo<T>::value>::type 
    //                                     ~~~~~~~^
    Foo<C, Ts...>::bar(T v) { /**/ }
    

    as explained in Where and why do I have to put the “template” and “typename” keywords?