Does optional typename apply to concept?

Viewed 145

GCC implemented P0634R3 that discards the need of specifying typename when the type is in known context.

Does it apply to concept as well?

Because the following code does not compile:

template<typename T>
concept sample_concept =
    std::default_initializable<T::value_type> &&
    requires (T t) {
        { t.some_func(std::declval<T::some_type>()) }
            -> std::same_as<T::iterator>;
    };

But when I specify typename in front of T::value_type and T::iterator, it compiles.

1 Answers

From the paper, emphasis mine:

We therefore propose we make typename optional in a number of commonplace contexts that are known to only permit type names.

That paper makes typename optional only in those places where you need to have a type. On the right-hand side of an alias declaration, needs to be a type. In a static_cast, needs to be a type, etc.

But here:

template<typename T>
concept sample_concept = std::default_initializable<T::value_type>;

That's not the case. While default_initializable's parameter is a type parameter, you can have concepts which take non-type template parameters or template template parameters too. So it's not a situation that only permits type names, so typename is still mandatory here.

You could ask: well, specifically in concepts, since you cannot overload a concept or (currently) have dependent concepts, you could just look in the concept and see if it takes a type or not. But that's a big increase in complexity for a small amount of gain, which would become both more complex and smaller if we ever added dependent concepts in the future anyway.

Related