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 14:24:14 -0500
On Sun, Mar 6, 2022 at 2:03 PM Lénárd Szolnoki via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> On Sun, 6 Mar 2022 19:54:04 +0100 Bo Persson via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> > On 2022-03-06 at 17:17, David Jones via Std-Proposals wrote:
> > > Under your proposal, it would have to mean the same as "x =
> > > f(1, 2, /*some defaulted thing*/)".
> > >
> > > Under my proposal, "x = f(1,2,)" and "x = f(1,2)" would be
> > > identical, as long is f is a function with default values supplied
> > > for every argument after the second.
> >
> > I'm not convinced that turning typos into valid code is an
> > improvement. :-)
> >
> > How do we know that f(1,2,) means "I want a default 3rd parameter"
> > and not "oops, I slipped on the keyboard"?
>
> In my understanding f(1,2,) and f(1,2) could mean the same thing
> always, not only when there are default parameters in the function
> declaration. So there is no "subtle difference" to worry about.
>

Right, I buy that.
So then that raises a new question about the intended semantics. Consider
    int f(int x, int y); // #1
    int f(int x, long y=4, int z=5); // #2
    int test() { return f(1, 2,); }
Without the trailing comma, this is unambiguous C++20; it calls f #1.
With trailing comma as shown, what would this mean? In my previous message,
I'd assumed it would unambiguously call #2 (because #1 doesn't have enough
function parameters to absorb all the commas). But in your reply, it seems
that it would unambiguously call #1, is that right?
Now consider:
    int g(int x, int y); // #1
    int g(int x, long y); // #2
    int g(int x, long y=4, int z=5); // #3
    int test() { return g(1,, 2); }
With only a single comma, this is unambiguous C++20; it calls g #1.
With two commas as shown, what would this mean? Would it unambiguously call
#3? or would it be ambiguous between #1 and #3?

Basically, there's a lot of problems to consider here. And you'll have to
consider them for real, if you want to propose this. But I also don't want
to seem to encourage you to consider them, because IMO that consideration
would be wasted effort because all you'd end up with would be a *very
well-considered* proposal that is still bad and thus stands no chance in
committee.


Perhaps you should focus on Tony Tables first. Write down something that
you have to write today, in your real codebase, that strikes you as too
verbose. Then, write down how you'd like it to look instead. For example
(the only example we've seen in this thread so far AFAIK, and it's not even
what you're actually proposing):

==Today==
namespace my {
    template<class T> using vector = vector<T, MyAlloc<T>>;
    template<class T> using set = set<T, std::less<T>, MyAlloc<T>>;
}
my::vector<int> v;
my::set<int> s;

==Tomorrow==
std::vector<int, MyAlloc<int>> v;
std::set<int,, MyAlloc<int>> s;

That Tony Table strikes me as a *10000% excellent *reason to keep the
status quo. The "Tomorrow" code is just strictly worse in every possible
way.

–Arthur

Received on 2022-03-06 19:24:26