On Sun, Mar 6, 2022 at 10:26 AM David Jones via Std-Proposals <std-proposals@lists.isocpp.org> 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