| Document number: | P4327R0 |
| Date: | 2026-06-21 |
| Audience: | Evolution Working Group (EWG) |
| Reply-to: | Ungureanu Radu-Andrei <radu.ungureanu@socopon.com> |
This paper introduces a shorthand syntax for specifying default function arguments using direct-list-initialization syntax.
This proposal would allow:
struct X {
explicit X(int);
};
void f(X x{5});with semantics equivalent to:
void f(X x = X{5});While this proposal does not introduce new expressive power, it’s purpose is to reduce redundancy and allow programmers to express default initialization in a style consistent with direct-list-initialization used elsewhere in the language.
C++ already promotes brace initialization as a uniform initialization syntax. Variables, data members, member initializer lists, and aggregate members can all be initialized directly using braces.
For example:
std::string s{"Hello"};
int i{5};Default function arguments are one of the few places where direct initialization requires repetition of the parameter type:
void f(std::string s = std::string{"hello"})This repetition is especially noticeable when:
This proposal is intended to primarily improve readability and conciseness. It does not indent to change overload resolution or initialization semantics.
This proposal is a pure language extension. It introduces no library changes and does not require any modifications to any standard library facilities.
This proposal is also fully backward compatible, because it only affects forms that are currently ill-formed or can be unambiguously determined from existing constructs.
The design of this proposal is to be purely syntactic sugar. A parameter declaration of the form:
T x{args...}within a parameter-declaration-list is treated as if it
were written as:
T x = T{args...}During discussions on the std-proposals list, concerns were raised about interactions with existing parsing rules.
For example:
T g(T{5});currently has a meaning unrelated to function parameter default arguments. In order to avoid this ambiguity, this proposal applies only to parameters that have an identifier:
T g(T x{5}); // proposed: valid
T g(T{5}); // declares g as a variable initialized with T{5} as constructor argumentThis preserves existing behavior for unnamed parameters.
Current syntax already allows the same semantics:
void f(X x = X{5});However, it requires repeating the type name and is inconsistent with direct-initialization style used elsewhere.
During discussion, variants such as:
X g(auto x = X{5});were suggested. However, the semantics are not the same, as g here would become a templated function, and because of the deduction semantics they are substantially more complex than a simple syntactic transformation. This proposal intentionally avoids any type deduction.
Another alternative is to avoid default arguments and instead provide an overload:
T f(T x);
T f() {
return f(T{5});
}However this is not equivalent, it requires an additional declaration, affects overloads, and is much more verbose. It also does not scale well at when multiple parameters have defaults, such as:
T f(X x = X{1}, Y y = Y{2}, Z z = Z{3});While this approach is a valid workaround, it does not directly address the goal of providing a concise direct-list-initialization syntax:
T f(X x{1}, Y y{2}, Z z{3});A parameter declaration may contain a braced-init-list immediately
following the declarator.
parameter-declaration:
attribute-specifier-seqopt thisopt decl-specifier-seq declarator
attribute-specifier-seqopt decl-specifier-seq declarator = initializer-clause
attribute-specifier-seqopt decl-specifier-seq declarator braced-init-list <- new
attribute-specifier-seqopt thisopt decl-specifier-seq abstract-declaratoropt
attribute-specifier-seqopt decl-specifier-seq abstract-declaratoropt = initializer-clause
Such a declaration would be interpreted as if it were written as:
attribute-specifier-seqopt decl-specifier-seq declarator = braced-init-list
This syntax is only permitted when:
declarator,braced-init-list appears immediately after the
identifier,Thanks to Halalaluyafail3 for raising concerns involving unnamed parameters, Alejandro Colomar for raising concerns about human readability, Sebastian Wittmeier for suggesting a deduction-based approach, Bo Persson for overload-based suggestion and Simon Schröder for observations regarding auto-based alternatives.