Date: Fri, 18 Sep 2026 15:03:50 +0800
Consider this declaration:
```cpp
void func(auto&& arg = 42);
int main()
{
func();
}
```
Both gcc and clang reject the call:
```text
[shyeyian_at_core cppmake]$ g++ -std=c++26 test/main.cpp
test/main.cpp: In function 'int main()':
test/main.cpp:5:9: error: no matching function for call to 'func()'
5 | func();
| ~~~~^~
* there is 1 candidate
* candidate 1: 'template<class auto:1> void func(auto:1&&)'
test/main.cpp:1:6:
1 | void func(auto&& arg = 1);
| ^~~~
* template argument deduction/substitution failed:
* couldn't deduce template parameter 'auto:1'
test/main.cpp:5:9:
5 | func();
| ~~~~^~
[shyeyian_at_core cppmake]$ clang++ -std=c++26 test/main.cpp
test/main.cpp:5:5: error: no matching function for call to 'func'
5 | func();
| ^~~~
test/main.cpp:1:6: note: candidate template ignored: couldn't infer
template argument 'arg:auto'
1 | void func(auto&& arg = 1);
| ^
1 error generated.
[shyeyian_at_core cppmake]$
```
This follows from the current rules: the declaration is an abbreviated
function template. In other words, it is effectively equivalent to:
```cpp
template<class T>
void func(T&& arg = 42);
```
But the declaration already contains a default expression with a known
type! I hope the declaration to be equivalent to
```cpp
template<class T = decltype(42)>
void func(T&& arg = 42);
```
This would make `func()` well-formed without changing calls that supply
an argument. In those calls, ordinary template argument deduction would
still determine `T`; the default template argument would be used only
when deduction does not provide one.
What do you think of this behavior? Are there any compatibility
concerns I may have overlooked?
```cpp
void func(auto&& arg = 42);
int main()
{
func();
}
```
Both gcc and clang reject the call:
```text
[shyeyian_at_core cppmake]$ g++ -std=c++26 test/main.cpp
test/main.cpp: In function 'int main()':
test/main.cpp:5:9: error: no matching function for call to 'func()'
5 | func();
| ~~~~^~
* there is 1 candidate
* candidate 1: 'template<class auto:1> void func(auto:1&&)'
test/main.cpp:1:6:
1 | void func(auto&& arg = 1);
| ^~~~
* template argument deduction/substitution failed:
* couldn't deduce template parameter 'auto:1'
test/main.cpp:5:9:
5 | func();
| ~~~~^~
[shyeyian_at_core cppmake]$ clang++ -std=c++26 test/main.cpp
test/main.cpp:5:5: error: no matching function for call to 'func'
5 | func();
| ^~~~
test/main.cpp:1:6: note: candidate template ignored: couldn't infer
template argument 'arg:auto'
1 | void func(auto&& arg = 1);
| ^
1 error generated.
[shyeyian_at_core cppmake]$
```
This follows from the current rules: the declaration is an abbreviated
function template. In other words, it is effectively equivalent to:
```cpp
template<class T>
void func(T&& arg = 42);
```
But the declaration already contains a default expression with a known
type! I hope the declaration to be equivalent to
```cpp
template<class T = decltype(42)>
void func(T&& arg = 42);
```
This would make `func()` well-formed without changing calls that supply
an argument. In those calls, ordinary template argument deduction would
still determine `T`; the default template argument would be used only
when deduction does not provide one.
What do you think of this behavior? Are there any compatibility
concerns I may have overlooked?
Received on 2026-09-18 07:04:22
