C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Labelled parameters

From: Jens Maurer <jens.maurer_at_[hidden]>
Date: Mon, 5 Jan 2026 13:38:47 +0100
I think we want to be ABI-stable when enabling a function to
be called with named parameters, during code evolution.
Anything involving extra layers of types likely doesn't do that.

And I agree with Ville that named parameters need to be opt-in,
i.e. the function declaration should expressly indicate that
something can be called with named parameters (and thus the
chosen parameter names are promised to be stable).


Before, in some library (not necessarily the standard library):

void f(int x, bool y);
// not the best names, but not really an issue; can be fixed
// by the library at any time without disturbing callers

After migrating to C++xy with named parameters and upgrading the
library API to allow for a nicer call syntax:

/* marker */ void f(int nitems, bool allocate);

This "after" transition step marks the spot where the library author
promises stable parameter names going forward. (And hopefully has
given some thought to those names.)

Now, there were also feature requests asking for some form of mixed
positional / named parameters; if that's not just a choice by the
caller, but also a feature choice of the function declaration, then
the opt-in marker might naturally appear at the boundary between
positional and named:

void f(/* marker */ int nitems, bool allocate); // both are named parameters

Jens





On 1/5/26 11:25, David Brown via Std-Proposals wrote:
>
>
> On 05/01/2026 09:10, Jan Schultke via Std-Proposals wrote:
>>
>>
>> Strong types are never realistically going to happen. I don't want to write
>>
>> std::memcpy(std::memcpy_dest_ptr(to), std::memcpy_source_ptr(from),
>> size);
>>
>> std::to_chars(begin, end, std::to_chars_base(16));
>>
>> I want to write
>>
>> std::memcpy(.dest = to, .src = from, .count = size);
>> std::to_chars(begin, end, .base = 16);
>>
>>
>> Outside of a few select places, I don't see much appetite for creating
>> countless additional types. In some cases, having some kind of numeric
>> range type or using std::spanwould help.
>>
>
> (This post is not a proposal - it's merely an idea that might be useful
> for labelled parameters and more general use. It might also be fatally
> flawed in some way that I haven't considered.)
>
>
> Strong types for naming parameters have the advantage that they already
> exist in the language, and already work. But they have the disadvantage
> of being verbose - both in defining the types, and in their usage. You
> end up with something like this (a real "Parameter" template would
> likely use rvalue references) :
>
> template <auto N, typename T> class Parameter {
> T value_;
> public :
> Parameter(T v) : value_(v) {}
> explicit operator T () { return value_; }
> };
>
> namespace my_lib {
> namespace foo_param {
> using X = Parameter<[](){ return "x"; }, int>;
> using Y = Parameter<[](){ return "y"; }, int>;
> }
> int foo(foo_param::X x, foo_param::Y y) {
> int x_ { x };
> int y_ { y };
> return x_ * x_ + y_;
> }
> int foo(foo_param::Y y, foo_param::X x) {
> return foo(foo_param::X(x), foo_param::Y(y));
> }
> }; // namespace ns
>
> int bar(int x, int y) {
> return my_lib::foo(my_lib::foo_param::X(x),
> my_lib::foo_param::Y(y));
> }
>
> int bar2(int x, int y) {
> return my_lib::foo(my_lib::foo_param::Y(y),
> my_lib::foo_param::X(x));
> }
>
>
> Is there any way that this could be simplified? Suppose it were
> possible to declare "foo" with :
>
> using namespace foo_param
> int foo(X x, Y y) {
> int x_ { x };
> int y_ { y };
> return x_ * x_ + y_;
> }
> using namespace foo_param
> int foo(Y y, X x) {
> return foo(X(x), Y(y));
> }
>
> This new "using" would inject the "foo_param" namespace (inside the
> "my_lib" namespace) into the lookup namespaces for parameters in the
> function call. You still have plenty of boilerplate code for the
> declaration of "foo", but it's usage now becomes :
>
> int bar(int x, int y) {
> return my_lib::foo(X(x), Y(y));
> }
>
> which is a huge improvement.
>
> It is also a general feature - it would not have to be restricted to
> just the parameter names, but could include "using" declarations for
> scoped enumerations or other identifiers that would often be convenient
> for users of the function "foo". The aim is to get the benefits of
> scopes and namespaces for type safety, scalability, modularity and
> clarity, while reducing the visual overhead when scopes are clear from
> the context.
>
>
> The next step would then be a way to inject types into this "function
> parameter" scope within the declaration of the function, so that the
> boilerplate on the definition of "foo" could be reduced. I have no good
> ideas about how that could be done neatly. But it is possible that it
> could be handled using reflection - first declare an implementation
> function "int foo_imp(int x, int y);" and then use a metafunction call
> "auto foo = std::named_parameters(foo_imp);" to declare the function
> with strong parameter types. I don't think reflection currently gives
> access to the names of function parameters, however.
>
>

Received on 2026-01-05 12:38:51