Date: Tue, 6 Jan 2026 08:07:08 +0100
> On Jan 5, 2026, at 11:26 AM, David Brown via Std-Proposals <std-proposals_at_[hidden]> 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.)
Your suggestion sounds similar to the “labelled parameters” proposal that already exists.
I don’t think strong types are really helpful. What I’m hoping for named parameters is that I can also switch up their order. The advantage? I don’t have to remember their order if there is no reasonable order. (This makes overload resolution slightly more complex, but I think it’s solvable.)
I agree with others that we need a mechanism that can be compatible with C. I believe that C tends to have longer argument lists because they don’t have classes and because they don’t have overloads (the latter means you always have to provide ALL parameters).
I would claim that for future libraries (but not existing ones) the use of overloading (with different number of arguments, but not with different types) can be reduced. For this we could heavily use named arguments with default parameters. The question would be if we want to lift the current restriction that only the last parameters can have default parameters:
void foo(int x, int y=0, int z);
We could allow this, but we would have to require that ‘z’ is only accessible by name (not position).
>
>
> 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.
>
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
>
>
>> 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.)
Your suggestion sounds similar to the “labelled parameters” proposal that already exists.
I don’t think strong types are really helpful. What I’m hoping for named parameters is that I can also switch up their order. The advantage? I don’t have to remember their order if there is no reasonable order. (This makes overload resolution slightly more complex, but I think it’s solvable.)
I agree with others that we need a mechanism that can be compatible with C. I believe that C tends to have longer argument lists because they don’t have classes and because they don’t have overloads (the latter means you always have to provide ALL parameters).
I would claim that for future libraries (but not existing ones) the use of overloading (with different number of arguments, but not with different types) can be reduced. For this we could heavily use named arguments with default parameters. The question would be if we want to lift the current restriction that only the last parameters can have default parameters:
void foo(int x, int y=0, int z);
We could allow this, but we would have to require that ‘z’ is only accessible by name (not position).
>
>
> 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.
>
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2026-01-06 07:07:25
