Mikhail
Mikhail

Reputation: 8028

Why is a `std::remove_cv<_Iter>::type` not a type?

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

Answers (1)

songyuanyao
songyuanyao

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:

Upvotes: 5

Related Questions