C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Implicitly accepting leading default function/template argument values

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Sun, 6 Mar 2022 10:54:21 -0500
On Sun, Mar 6, 2022 at 10:26 AM David Jones via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Consider the function
>
> void foo(int i = 1, int j = 2, int k = 3);
>
> *Trailing *default argument values can be accepted implicitly by simply skipping
> them in the function call:
>
> foo(); //Accept default values for i, j, and k
> foo(1); //Accept default values for j and k, supply value for i
> foo(1,2); //Accept default value for k, supply values for i and j
>
> But to my knowledge, there is no method for implicitly accepting
> *leading *default argument values - they must be copied out explicitly:
>
> foo(1,2,5); //Accept default values for i and j by copying them out
> explicitly, supply value for k
>
> I suggest that this could be done implicitly thus:
>
> foo(,,2); //Accept default values for i and j, supply value for k
> foo(,1); //Accept default values for i and k, supply value for j
>

That would close the door on the vastly vastly more useful Python-style
syntax
    x = f(
        1,
        2,
    )
which in C++ today means "syntax error," but in Python and other modern
languages means the same as "x = f(1, 2)".
Under your proposal, it would have to mean the same as "x = f(1, 2, /*some
defaulted thing*/)".

By the way, how would that even work, with overload resolution? I guess
you're picturing something kind of like what `f<>(1, 2)` does today — f<>
says "I'd like to call a function f that can take two ints, but btw, please
only consider fs that are template instantiations, not ordinary
functions." So `f(1,2,)` would say "I'd like to call a function f that can
take two ints, but btw, please only consider fs that *also* contain at
least one defaulted argument after the first two." The f<> quirk is pretty
awful IMHO, and I would not like to see any new similar quirks in that
area. So *also for that reason*, your proposal is a bad one.


This could also apply to default template arguments. For example, to
> specify a custom allocator for std::set the comparison type must currently
> also be explicitly specified :
>
> std::set<int, std::less<int>, Myalloc>; //OK, but std::less<int> is
> superfluous.
> std::set<int,, Myalloc>; //Currently an error
>

Look at how std::pmr::set<int> does it, and consider writing your own
my::allocated_set<int> along the same lines.

–Arthur

Received on 2022-03-06 15:54:33