---
title: "Direct-list-initialization syntax for default function arguments"
document: P4327R0
date: 2026-06-21
audience: Evolution Working Group (EWG)
reply-to:
  - "Radu-Andrei <radu.ungureanu@socopon.com>"
---



# II. Motivation and Scope

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:

```cpp
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:

```cpp
void f(std::string s = std::string{"hello"})
```

This repetition is especially noticeable when:

- the type name is long;
- the constructor is explicit;
- the parameter type is itself templated.

This proposal is intended to primarily improve readability and conciseness. It does not indent to change overload resolution or initialization semantics.

# III. Impact On the Standard

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.

# IV. Design Decisions

## Semantics

The design of this proposal is to be purely syntactic sugar. A parameter declaration of the form:

```cpp
T x{args...}
```

within a `parameter-declaration-list` is treated as if it were written as:

```cpp
T x = T{args...}
```

## Named parameters only

During discussions on the std-proposals list, concerns were raised about interactions with existing parsing rules.

For example:

```cpp
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:

```cpp
T g(T x{5}); // proposed: valid
T g(T{5});   // declares g as a variable initialized with T{5} as constructor argument
```

This preserves existing behavior for unnamed parameters.

## Alternatives considered

### Status-quo

Current syntax already allows the same semantics:

```cpp
void f(X x = X{5});
```

However, it requires repeating the type name and is inconsistent with direct-initialization style used elsewhere.

### Deduction-based approach

During discussion, variants such as:

```cpp
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.

### Overload-based approach

Another alternative is to avoid default arguments and instead provide an overload:

```cpp
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:

```cpp
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:

```cpp
T f(X x{1}, Y y{2}, Z z{3});
```

# V. Technical Specifications

## Overview

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
```

## Constraints

This syntax is only permitted when:

- the parameter has a `declarator`,
- the `braced-init-list` appears immediately after the identifier,
- the declaration appears with a parameter-declaration-list

# VI. Acknowledgements

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.
