C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Make typename optional when used with a name dependent on a constrained template

From: Christoph Meyer <christoph.meyer.2006_at_[hidden]>
Date: Wed, 22 Feb 2023 11:06:33 +0100
On Tuesday, 21 February 2023 22:45 MET, Ville Voutilainen via Std-Proposals
wrote:
> On Tue, 21 Feb 2023 at 23:28, Christoph Meyer via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
>> [using markdown]
>> Hello,
>> this very first draft of the proposal is about making the `typename`
>> keyword optional when used together with a name that is dependent on a
>> constrained template whose constraints guarantee that the dependent
>> name is indeed a typename.
>> Explanation
>> ===========
>> Please consider the following example:
>> ```c++
>> template <typename T>
>> concept has_inner_type = requires
>> {
>> typename T::inner;
>> };
>> template <typename BaseType>
>> struct my_pointer
>> {
>> typedef BaseType* inner;
>> };
>> template <has_inner_type T>
>> void foo(T value)
>> {
>> typename T::inner innerValue;
>> // do something with value and innerValue
>> }
>> int main(void)
>> {
>> my_pointer<int> p;
>> foo(p);
>> return 0;
>> }
>> ```
>> The type requirement `typename T::inner;` ensures that the name
>> `inner` dependent on any type `T` that matches said requirement is
>> always a type and not a value, technically making the keyword
>> `typename` obsolete in that context.
>> The function `foo` would then read like this:
>> ```c++
>> template <has_inner_type T>
>> void foo(T value)
>> {
>> T::inner innerValue;
>> // do something with value and innerValue
>> }
>> ```
>> Motivation
>> ==========
>> The whole idea behind type template parameters is to generalize
>> functions, classes, structs or variables by giving the programmer the
>> possibility to swap out a type template parameter with a variety of
>> types. In most cases, it is possible to use type template parameters
>> *as if* they were real types and actually swapping type template
>> parameters with actual types (like with macros) would result in valid
>> code, which in my opinion feels natural and matches most programmers'
>> way of thinking about templates.
>> Making the `typename` keyword optional as describes above would bring
>> us a step closer to being able to use a type template parameter like a
>> real type.
>> Please let me know your opinions on this proposal, and please excuse
>> possible formal or linguistic errors, as this is my first proposal and
>> I do not speak English as a native language.
>
>
> Three thoughts:
>
> 1) while I can't do it for non-dependent cases, for dependent cases
> it's kinda nice to be able to tell apart types from variables
> at a glance, without having to look at other code far away. But as I
> said, that's not a thing for non-dependent cases, so this
> is not a big concern.
>
> 2) I suppose it's beneficial for an implementation efficiency-wise not
> to have to do that extra lookup into a concept definition to tell
> apart
> a type and a variable when its name is dependent. I don't know how to
> quantify that, so that's not a huge concern, but we're warming up.
>
> 3) the biggest concern is that the meaning of that name can change by
> action at a distance. Meaning that if you change the constraint
> of foo, now T::inner doesn't necessarily mean what it meant before,
> because it doesn't have 'typename' nailing down its typeness.
> That worries me fair amounts. For other cases of "down with
> 'typename'!", it's still unambiguously so that the name is always a
> type,
> and can never be anything else. Here it seems like it could be,
> because there's no syntactic indication of any kind, it's just a
> matter of
> looking up into a concept definition.

1) If you explicitly want to tell apart typenames from value names, you still have the option to do so.

2) see 1)

3) This is not specific to this proposal. Imagine a series of functions called in a chain which all take in a non-const glvalue and modify its value. If you declare the input value -- which is declared in another file far away -- const, everything breaks. If you wanted to double-ensure the typeness of a dependent name, you could still use the `typename` keyword.

I can totally understand your concerns about code clarity and readability but i think they don't justify forcing the programmer to introduce redundancy that could be avoided (like making the `override` keyword obligatory).
In my opinion, if you find yourself in the situation where it would be ambiguous if a name describes a type or a value, the problem lies in your code, not in the language itself.

Sincerely,
Christoph Meyer

Received on 2023-02-22 10:06:46