Consider this code:
template<typename T>
struct Foo
{
typedef T t_type;
};
template<typename T>
struct Bar
{
typedef T t_type;
};
template<typename U>
auto f() -> typename U::t_type::t_type
{
return typename U::t_type::t_type();
}
int main(int, char**)
{
typedef Foo<Bar<int>> Baz;
f<Baz>();
}
It doesn't compile under VS2012:
invalid explicit template argument(s) for 'U::t_type::{ctor} f(void)'
Seemingly, the compiler is concluding that the second t_type
in typename U::t_type::t_type
is naming a constructor rather than an identically-named nested type. Is there anything I can do to help clarify the situation?
First you're missing a typename
keyword
template<typename U>
auto f() -> typename U::t_type::t_type
{
return typename U::t_type::t_type();
}
and main should have arguments (int,char**)
.
That said..
this has already been reported and apparently fixed ([will be/has been] shipped in an unspecified "future version"). MSVC 2013 update 4 is also affected.
The proposed workaround is:
template<typename T>
struct Foo
{
typedef T t_type;
};
template<typename T>
struct Bar
{
typedef T t_type;
};
template<typename U>
auto f() -> typename U::t_type::template t_type
^^^^^^^^
{
return typename U::t_type::t_type();
}
int main(int, char**)
{
typedef Foo<Bar<int>> Baz;
f<Baz>();
}
although if you use the code above everything proceeds as in the following image: