Why C++ Doesn't Support Named Parameter

Why doesn't C++ support named parameters?

Why doesn't C++ support named parameters?

Because such feature has not been introduced to the standard. The feature didn't (and doesn't) exist in C either, which is what C++ was originally based on.

Will it support it in a future version of the C++ standard?

A proposal was written for it. But the proposal was rejected.

A fundamental problem in C++ is that the names of the parameters in function declarations aren't significant, and following program is well-defined:

void foo(int x, int y);
void foo(int y, int x); // re-declaration of the same function
void foo(int, int); // parameter names are optional
void foo(int a, int b) {} // definition of the same function

If named parameters were introduced to the language, then what parameters would be passed here?

foo(x=42, b=42);

Named parameters require significantly different, and backwards incompatible system of parameter passing.


You can emulate named parameters by using a single parameter of class type:

struct args {
int a = 42;
float b = 3.14;
};

void foo(args);

// usage
args a{};
a.b = 10.1;
foo(a);
// or in C++20
foo({.b = 10.1});

How to use named parameters in c++

Neither C nor C++ supports named parameters.

The closest you can come to this is to define a struct with all of the parameters:

struct cal_params {
int year;
int month;
int day;
};

Define the function to take an instance of that struct:

char *calendar(struct cal_params params)
{
...
}

Then call the function with a compound literal using designated initializers:

char *str = calendar((struct cal_params){ .year=2021, .month=9, .day=4});

Is there a way in C++ to pass arguments by name like in python?

There are no named function parameters in C++, but you can achieve a similar effect with designated initializers from C++20.

Take all the function parameters and put them into a struct:

struct S 
{
int a{}, b{}, c{}, d{};
};

Now modify your function to take an instance of that struct (by const& for efficiency)

void foo(S s) 
{
std::cout << s.a << " " << s.b << " " << s.c << " " << s.d; // for example
}

and now you can call the function like this:

foo({.a = 2, .c = 3});  // prints 2 0 3 0 
// b and d get default values of 0

Here's a demo

Is there a nicer way to do c named arguments?

Sure.

struct toto {
unsigned age;
char name[25];
};

void func(struct toto);

...

func((struct toto){ .name = "you", .age = 18 });

or if you want you may wrap that in a macro

#define FUNC(...) func((struct toto){ __VA_ARGS__ })
...
FUNC(.name = "you", .age = 18 );

A way to emulate named arguments in C

Kinda, sorta, with a compound literal and designated initializers:

typedef struct foo_args {
int a;
int b;
int c;
} foo_args;

// Later

foo(&(foo_args) {
.a = 2,
.c = 3,
.b = 1
});

But I honestly wouldn't bother. It requires you to bend the function definition to accept a pointer, and makes calling it cumbersome.

What are the rules for named arguments and why?

the compiler might be able to figure it out but for us mere humans it would be nearly impossible to know if 25 refers to the 1st or 3rd parameter. Especially since it opens up the posibility of mixing arguments. why not

MyFunction(firstname: "josh", 25, "smith", someotherargument: 42)

How would you interpret this, 25 for age and smith for lastname? make a rule for it and a compiler can implement it. But what would make sense to humans. Code obfuscation shouldn't be that easy

A language should make it hard to make errors, not easier

NOTE: strange things start happening with the ordering if earlier arguments are named later. (like the firstname & smith in my example) because then becomes a puzzle for your unnamed arguments to be mapped to the right arguments. it could be done, but code shouldn't produce puzzles

When are named arguments useful?

Named arguments are meant to increase readability. For example I've just used one as such

public void MarkAsDone(bool skipped) {}

Now by invoking the method without the name we have an ambiguity

MarkAsDone(true); //does true mean that it is successfully done?

Which can be resolved by clarifying with a name

MarkAsDone(skipped: true);

I think using the named parameter makes the client code way less ambiguous.

Apart from that they can be used to uniquely identify an optional parameter when there's more than one with the same type

MarkAsDone(int first, int second=0, int third=0) {}

///

MarkAsDone(1, third: 3);

Forcing named arguments in C#

No, not in the C# language. It will always accept positional parameters if all the parameters are supplied.

You could build a custom FxCop rule or an StyleCop rule to enforce this - as pointed out in the comments, it is likely a StyleCop rule you would be interested in (thanks to Kris).



Related Topics



Leave a reply



Submit