C++ Logo


Advanced search

Re: Down with "template"! (up with the turbofish)

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Sat, 9 Oct 2021 10:06:26 -0400
On Fri, Oct 8, 2021 at 6:06 PM Jean-Baptiste Vallon Hoarau via
Std-Proposals <std-proposals_at_[hidden]> wrote:
> Arthur :
>> The proposed change merely takes code that people already avoid (because it is ugly) and introduces a special-case ad-hoc hack to make it still ugly but 7 characters shorter.
> I don't think that's fair to describe this as a hack. Most languages are written with simple top down, context-free parsing in mind, this would bring C++ a bit closer to that. At the very least it is not more of a hack than the present day syntax, while being much more palatable.

The reason why we need `template` there at all is because of context
sensitivity issues involved in using `<>` as a list of template
arguments. Your proposal opts to create a token that removes that

I believe his point is that, even though it's "simpler" than
`template`, you still have to do *something* that you wouldn't
ordinarily have to do. That is, you still have to know that you need
disambiguation syntax. As such, your proposal doesn't fix the C++
parser to take the expected code. It merely provides a different
spelling of the disambiguated code.

It's an improvement *only* in the number of characters used. You still
have to know that you need to use a special thing in these cases.

>> But our changes should find ways to improve the code people already write, like
>> template<enable_if_t<X,int>=0> // syntax error because ">=" is a token
> Do you have an example of a more pressing syntax problem outside of SFINAE? Because obviously the people who have to use enable_if will not be able to benefit from any syntax improvement, since they are stuck with an outdated compiler already.
> Personally, I waste time turning members functions templates into friends/or turn explicit into deducible parameters everyday. I've never, as far as I remember, stumbled on the issue you mentioned.
>> Which nobody will use, because in order to use it you have to know that the problem exists, and once you know the problem exists, the problem is already solved. The problems we should focus on solving are the problems that people tend to run into without understanding them.
> I don't find this convincing. What's "a problem you run into without understanding it"?


int foo(float());

The fact that `foo` is a function declaration, not a variable, is a
problem people routinely encounter. The compiler often spits out
something patently unhelpful in these cases (often not citing the
declaration line as the problem), thus requiring that a user go
looking for an explanation elsewhere.

This is similar to the SFINAE problem Arthur wrote about: the compile
error you get is unhelpful, it's not clear what the problem with the
code is, and therefore you're not sure what to do about it.

>The problem is not solved for all the programmers who know about it : the syntax is still bad and they have to waste time working around it.

The problem you're talking about is one that the compiler basically
tells you how to fix. "It looks like you tried to write a template
specialization, but you need to put 'template' there." You encountered
a problem and understand what you need to do to solve it.

> What's more practical? Having to use "::" in context dependent code or going out of your way to avoid members functions templates altogether?

You could just use `template`. If having to write 9 extra characters
is enough to make you fundamentally rewrite code, I don't see how
having to write 2 characters would make you stop. C++ didn't make
`std::get` a free function because making it a template member of
`tuple` would make it too ugly to call. We did it because it creates a
uniform interface for extracting members which other types (like
`pair`) can participate in.

It should also be pointed out that the lion's share of template
functions are written to use template argument deduction for all of
their parameters. So you only encounter this problem on a relatively
small number of member templates.

Even something like member `get` could be solved by having an overload
that takes a `std::integral_constant` parameter and using template
argument deduction to extract the value from it. You'd probably also
need a special literal suffix to make using integer literals easier to
use, so you could just use `x.get(0_ce)`.

Received on 2021-10-09 09:06:41