C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Explicitly specifying default arguments

From: Andrey Semashev <andrey.semashev_at_[hidden]>
Date: Thu, 2 Feb 2023 05:01:30 +0300
On 2/2/23 04:45, Andrey Semashev wrote:
> On 2/2/23 04:24, Jason McKesson via Std-Proposals wrote:
>>
>> It's interesting that you bring up perfect forwarding. Because
>> forwarding pretty much kills this idea (and most forms of named
>> parameters.
>>
>> That is, if you want `T t(1, default, 5);` to work, how do you propose
>> to make `optional<T> t(std::in_place, 1, default, 5);` work? Or better
>> yet, `std::thread thr(some_functor(), 1, default, 5);`?
>
> I do not propose to make that work. The proposal is just to be able to
> write "default" for arguments that have a default, nothing more. This is
> not intended to work across an abstraction layer such as std::thread,
> std::bind, std::optional, function pointers, etc.
>
>> The closest I could come up with is that the expression `default` is a
>> prvalue of some `nullptr_t`-style type.
>
> `default` would not be an expression in a full sense. It would be a core
> language placeholder that is replaced by the default argument
> expression. That is:
>
> template< typename T >
> void foo(T const& str = "Hello");
>
> foo(default); // literally equivalent to foo("Hello");,
> // which makes T be char[6].
>
> Just to be clear, if `default` is used for an argument without a
> default, the program is ill-formed (same as when you don't specify an
> argument that doesn't have a default).
>
>> Which opens up a whole new can of worms regarding overload resolution
>> and function selection. Plus, there's the fact that "has a default
>> parameter" is not an innate property of a function; it's just
>> something that a particular declaration happens to have.
>
> Per the above, overload resolution is unaffected, since the call is
> functionally equivalent to the caller not specifying the argument at all.

A few examples to illustrate:

  void test(int, double = 1.0, const char* = nullptr); // #1
  void test(int, long = 10l, const int* = nullptr, char = 'a'); // #2

  test(10); // ambiguous
  test(10, default); // ambiguous
  test(10, 20l); // calls #2
  test(10, 20l, default); // calls #2
  test(10, default, "Hello"); // calls #1
  test(10, default, default); // ambiguous
  test(10, default, default, default); // calls #2

>> I would argue that if you cannot solve the forwarding problem for
>> default parameters, then you're basically un-perfecting perfect
>> forwarding (not that it's actually perfect as is, but it's not nearly
>> this bad). And that's not worth the gains of being able to default
>> parameters.
>
> I'm not sure why you think that default argument values need to be
> forwarded - this is not possible now, and it was not my intention to
> support it with this proposal.
>

Received on 2023-02-02 02:01:38