Date: Sun, 22 Mar 2026 10:17:10 +0100
On 2026-03-22 at 09:25, Ivan Lazaric via Std-Proposals wrote:
> Would it be possible/make sense/be better to default the template
> parameter to decltype of expression when possible?
>
> void func(auto arg = 0) { }
>
> // equivalent to:
>
> template<typename Arg = decltype(0)>
> void func(Arg arg = 0) { }>
It would be less typing to just add an overload:
void func() { func(0); }
> On Sun, Mar 22, 2026 at 9:20 AM Jan Schultke via Std-Proposals <std-
> proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>> wrote:
>
> auto in function parameters just makes the function an abbreviated
> function template. It's just a shorthand notation for a "regular"
> function template.
>
> The following code is valid for example:
>
> void func(auto arg = 0) { }
>
> int main() {
> func<void*>();
> }
>
>
> With that knowledge, trying to deduce the type from the default
> argument doesn't make sense. It would take away your ability to
> write templates where you use a "symbolic" default argument like 0
> or {} that is converted to the specified type. It may be counter-
> intuitive for the abbreviated syntax, but I think it would be
> equally confusing if there were major differences between
> abbreviated and unabbreviated templates too.
>
> On Sun, 22 Mar 2026 at 05:11, 叶易安 via Std-Proposals <std-
> proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>>
> wrote:
>
> Hi, std-proposals mailing list. I'm a C++ learner, and i'm
> confused in a C++ grammar related question below. Could you
> please help and give some of your advice? Thanks!
>
> In this code,
>
> ===== tmp.cpp =====
> int func(auto arg = 42) { return int(arg); }
> int value = func(); // Expected: with default argument = 42, and
> `auto` deduced into `int`.
> =====
>
> We expect that the default argument is 42, and `auto` is
> **deduced** into `int`.
>
> But actually, in the current C++ standard, this `auto` can be
> deduced by user-provided arguments, but **cannot** be deduced by
> default-provided arguments. C++ complains about we cannot choose
> `int` as the default type. Let's see the outputs.
>
> ===== C++ draft =====
> https://eel.is/c++draft/dcl.fct.default <https://eel.is/c+
> +draft/dcl.fct.default>, which does not mentioned this case.
> =====
>
> ===== cppreference =====
> https://cppreference.com/w/cpp/language/default_arguments.html
> <https://cppreference.com/w/cpp/language/
> default_arguments.html>, which does not mentioned this case.
> =====
>
> ===== g++ (version=15) =====
> shyeyian_at_macbook tmp % g++-15 -std=c++26 tmp.cpp -o tmp
> tmp.cpp:2:17: error: no matching function for call to 'func()'
> 2 | int value = func();
> | ~~~~^~
> tmp.cpp:2:17: note: there is 1 candidate
> tmp.cpp:1:5: note: candidate 1: 'template<class auto:1> int
> func(auto:1)'
> 1 | int func(auto arg = 42) { return arg * 2; }
> | ^~~~
> tmp.cpp:1:5: note: template argument deduction/substitution failed:
> tmp.cpp:2:17: note: couldn't deduce template parameter 'auto:1'
> 2 | int value = func();
> | ~~~~^~
> =====
>
> ===== clang++ (version=22) =====
> shyeyian_at_macbook tmp % clang++ -std=c++26 tmp.cpp -o tmp
> tmp.cpp:2:13: error: no matching function for call to 'func'
> 2 | int value = func();
> | ^~~~
> tmp.cpp:1:5: note: candidate template ignored: couldn't infer
> template argument
> 'arg:auto'
> 1 | int func(auto arg = 42) { return arg * 2; }
> | ^
> 1 error generated.
> =====
>
> Because the default argument is a value, it always has a type,
> and then this `auto` here is always deducable. So that, In my
> perspective, this default argument should work with default type
> as `int`.
>
> Would it be possible/make sense/be better to default the template
> parameter to decltype of expression when possible?
>
> void func(auto arg = 0) { }
>
> // equivalent to:
>
> template<typename Arg = decltype(0)>
> void func(Arg arg = 0) { }>
It would be less typing to just add an overload:
void func() { func(0); }
> On Sun, Mar 22, 2026 at 9:20 AM Jan Schultke via Std-Proposals <std-
> proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>> wrote:
>
> auto in function parameters just makes the function an abbreviated
> function template. It's just a shorthand notation for a "regular"
> function template.
>
> The following code is valid for example:
>
> void func(auto arg = 0) { }
>
> int main() {
> func<void*>();
> }
>
>
> With that knowledge, trying to deduce the type from the default
> argument doesn't make sense. It would take away your ability to
> write templates where you use a "symbolic" default argument like 0
> or {} that is converted to the specified type. It may be counter-
> intuitive for the abbreviated syntax, but I think it would be
> equally confusing if there were major differences between
> abbreviated and unabbreviated templates too.
>
> On Sun, 22 Mar 2026 at 05:11, 叶易安 via Std-Proposals <std-
> proposals_at_[hidden] <mailto:std-proposals_at_[hidden]>>
> wrote:
>
> Hi, std-proposals mailing list. I'm a C++ learner, and i'm
> confused in a C++ grammar related question below. Could you
> please help and give some of your advice? Thanks!
>
> In this code,
>
> ===== tmp.cpp =====
> int func(auto arg = 42) { return int(arg); }
> int value = func(); // Expected: with default argument = 42, and
> `auto` deduced into `int`.
> =====
>
> We expect that the default argument is 42, and `auto` is
> **deduced** into `int`.
>
> But actually, in the current C++ standard, this `auto` can be
> deduced by user-provided arguments, but **cannot** be deduced by
> default-provided arguments. C++ complains about we cannot choose
> `int` as the default type. Let's see the outputs.
>
> ===== C++ draft =====
> https://eel.is/c++draft/dcl.fct.default <https://eel.is/c+
> +draft/dcl.fct.default>, which does not mentioned this case.
> =====
>
> ===== cppreference =====
> https://cppreference.com/w/cpp/language/default_arguments.html
> <https://cppreference.com/w/cpp/language/
> default_arguments.html>, which does not mentioned this case.
> =====
>
> ===== g++ (version=15) =====
> shyeyian_at_macbook tmp % g++-15 -std=c++26 tmp.cpp -o tmp
> tmp.cpp:2:17: error: no matching function for call to 'func()'
> 2 | int value = func();
> | ~~~~^~
> tmp.cpp:2:17: note: there is 1 candidate
> tmp.cpp:1:5: note: candidate 1: 'template<class auto:1> int
> func(auto:1)'
> 1 | int func(auto arg = 42) { return arg * 2; }
> | ^~~~
> tmp.cpp:1:5: note: template argument deduction/substitution failed:
> tmp.cpp:2:17: note: couldn't deduce template parameter 'auto:1'
> 2 | int value = func();
> | ~~~~^~
> =====
>
> ===== clang++ (version=22) =====
> shyeyian_at_macbook tmp % clang++ -std=c++26 tmp.cpp -o tmp
> tmp.cpp:2:13: error: no matching function for call to 'func'
> 2 | int value = func();
> | ^~~~
> tmp.cpp:1:5: note: candidate template ignored: couldn't infer
> template argument
> 'arg:auto'
> 1 | int func(auto arg = 42) { return arg * 2; }
> | ^
> 1 error generated.
> =====
>
> Because the default argument is a value, it always has a type,
> and then this `auto` here is always deducable. So that, In my
> perspective, this default argument should work with default type
> as `int`.
>
Received on 2026-03-22 09:17:17
