I have a class
template <typename T>
struct Trait { typedef std::false_type IsGood; };
template <>
struct Trait<int> { typedef std::true_type IsGood; };
A call like this fails to compile on 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>
{};
while
template <typename T>
class Foo <T, typename std::enable_if<std::is_same<std::true_type,
typename Trait<T>::IsGood>::value>::type>
{};
works -- why?
The error message is:
main.cpp(12): error C2039: 'type' : is not a member of 'std::tr1::enable_if<_Test>'
with
[
_Test=false
]
main.cpp(12): e开发者_如何学编程rror 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
You're using typename
at wrong place. This is correct:
template <typename T>
class Foo <T, typename std::enable_if<Trait<T>::IsGood::value>::type>
{}; // ^^^^^^^ here should be typename
Now it compiles fine: http://ideone.com/0SwO9
But you're using typename
as:
template <typename T>
class Foo <T, std::enable_if<typename Trait<T>::IsGood::value>::type>
{}; //^^^^^^^ wrong place
Trait<T>::IsGood::value
is not a type, So you cannot apply typename
on it.
GCC error message is very much clear:
prog.cpp:12:62: error: type/value mismatch at argument 1 in template parameter list for 'template<bool <anonymous>, class _Tp> struct std::enable_if'
See yourself : http://ideone.com/9ujJv
精彩评论