Date: Fri, 18 Sep 2026 09:15:47 +0000
On Friday, September 18th, 2026 at 10:04 AM, shyeyian via Std-Proposals <std-proposals_at_[hidden]> wrote:
> 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?
>
I think it's generally the right direction, or at least an easy one to
specify, though you'd have to take care of default arguments that refer
to other function arguments that aren't technically visible at the
template head. Something like:
void f(auto x, auto y = decltype(x)(42));
Another thing worth thinking about is whether providing an explicit
template argument should "disable" the corresponding default function
argument (so that a caller that provides an explicit template argument
must also provide an explicit function argument). There's something a
bit concerning about keeping the default value but overriding the type.
> 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?
>
I think it's generally the right direction, or at least an easy one to
specify, though you'd have to take care of default arguments that refer
to other function arguments that aren't technically visible at the
template head. Something like:
void f(auto x, auto y = decltype(x)(42));
Another thing worth thinking about is whether providing an explicit
template argument should "disable" the corresponding default function
argument (so that a caller that provides an explicit template argument
must also provide an explicit function argument). There's something a
bit concerning about keeping the default value but overriding the type.
Received on 2026-09-18 09:15:57
