Reputation: 8028
I have two versions of the what I'd expect to be the same function but gcc says version 1 is valid while version 2 gives a
expected a type, got 'std::remove_cv<_Iter>::type'
I don't quite understand this error, as I'd expect that the using
statement required a type, and wouldn't automatically promote a 'std::remove_cv<_Iter>::type'
to something else?
Can somebody explain whats going on here?
template<typename U,typename V> constexpr inline auto is_same_rcv() noexcept
{
//version 1 works
using u_underlying = std::remove_cv<U>::type;
using v_underlying = std::remove_cv<V>::type;
return std::is_same<u_underlying,v_underlying>::value;
}
and
template<typename U,typename V> constexpr inline auto is_same_rcv() noexcept
{
//version 2 doesn't work
using u_underlying = std::remove_cv<U>::type;
return std::is_same<u_underlying,std::remove_cv<V>::type>::value;
}
Associated godbolt
Edit for fun, it looks like clang and gcc different on the interpretation of the using keyword (see https://godbolt.org/z/P9Pcn6)
Upvotes: 2
Views: 253
Reputation: 172944
You need to use the keyword typename
to tell that the dependent names std::remove_cv<V>::type
is a type.
return std::is_same<u_underlying, typename std::remove_cv<V>::type>::value;
// ^^^^^^^^
In the using
statement typename
is not needed again since C++20.
In some contexts, only type names can validly appear. In these contexts, a dependent qualified name is assumed to name a type and no
typename
is required:
...
A qualified name that appears in type-id, where the smallest enclosing type-id is:
- ...
- the type-id in an alias declaration;
- ...
Upvotes: 5