Date: Fri, 9 Jan 2026 19:00:07 +0100
Yes sorry, I could have been a bit more clear and elaborate a little.
It is an implicit template (you can tell by the 'auto' inside the argument
list), but the constraint is applied after deduction rules. It means that
unless arg2 is deduced to exactly 'bool', the substitution is considered a
"failure" and SFINAE kicks in and forces the compiler to look for other
candidates (or a compilation error if no alternatives are around).
// Robin
On Fri, Jan 9, 2026, 18:48 Andre Kostur via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> That is a template. Also known as a constrained auto.
>
> On Fri, Jan 9, 2026 at 9:46 AM Steve Weinrich via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
> >
> > I believe concepts only work inside of templates.
> >
> >
> >
> > From: Std-Proposals <std-proposals-bounces_at_[hidden]> On Behalf
> Of Robin Savonen Söderholm via Std-Proposals
> > Sent: Friday, January 9, 2026 10:36 AM
> > To: C++ Proposals <std-proposals_at_[hidden]>
> > Cc: Robin Savonen Söderholm <robinsavonensoderholm_at_[hidden]>
> > Subject: Re: [std-proposals] resolving function overloading ambiguity
> for bool arguments
> >
> >
> >
> > You already can:
> >
> >
> >
> > void foo(double arg1, std::same_as<bool> auto arg2)...
> >
> >
> >
> > On Fri, Jan 9, 2026, 18:18 David Brown via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> >
> >
> >
> > On 09/01/2026 17:37, Steve Weinrich via Std-Proposals wrote:
> > > Consider two methods:
> > >
> > > void interest (double arg1, bool minor);
> > >
> > > void interest (double arg1, int factor);
> > >
> > > The call: interest(5.5, 5); is ambiguous because 5 will freely convert
> > > to a bool.
> >
> > No, it is not ambiguous - the best fit overload will be used. The rules
> > for overload resolution are a bit complicated, but in this case the
> > results are clear.
> >
> > <https://en.cppreference.com/w/cpp/language/overload_resolution.html>
> >
> > >
> > > I was wondering what y’all would think of narrowing this behavior by
> > > this addition:
> > >
> > > void interest (double arg1, *explicit* bool minor);
> > >
> > > Potentially, this could be applied to all arguments:
> > >
> > > void *explicit* interest (double arg1, bool minor);
> > >
> >
> > To me, a bigger issue is when you /don't/ have overloads :
> >
> >
> > void interest (double arg1, bool minor);
> >
> > In this situation, the implicit conversion of an int to a bool for
> > "interest(5.5, 5)" is likely to be an error on the programmer's side,
> > but it is accepted without question by C++ compilers. To avoid this,
> > some people use "strong bool" types that have much stricter implicit
> > conversions, such as :
> >
> > class Bool {
> > bool v;
> > public :
> > constexpr Bool(bool v) noexcept : v(v) {}
> > Bool(auto v) = delete;
> > explicit constexpr operator bool() const noexcept { return v; }
> > };
> >
> > Then you can declare the function :
> >
> > void interest (double arg1, Bool minor);
> >
> > and use it with a bool type as the second argument, but not with another
> > type that has an implicit conversion to bool.
> >
> > An alternative way to block non-bool calls would be to write :
> >
> > void interest (double arg1, bool minor);
> > void interest (double arg1, auto) = delete;
> >
> >
> > But it would be very nice (IMHO) if you could just write :
> >
> > void interest (double arg1, explicit bool minor);
> >
> > and get the same effect (that is, a function candidate would not be
> > considered "viable" in overload resolution if the second argument
> > required an implicit conversion sequence to the specified type).
> >
> > --
> > Std-Proposals mailing list
> > Std-Proposals_at_[hidden]
> > https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
> >
> > --
> > Std-Proposals mailing list
> > Std-Proposals_at_[hidden]
> > https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
It is an implicit template (you can tell by the 'auto' inside the argument
list), but the constraint is applied after deduction rules. It means that
unless arg2 is deduced to exactly 'bool', the substitution is considered a
"failure" and SFINAE kicks in and forces the compiler to look for other
candidates (or a compilation error if no alternatives are around).
// Robin
On Fri, Jan 9, 2026, 18:48 Andre Kostur via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> That is a template. Also known as a constrained auto.
>
> On Fri, Jan 9, 2026 at 9:46 AM Steve Weinrich via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
> >
> > I believe concepts only work inside of templates.
> >
> >
> >
> > From: Std-Proposals <std-proposals-bounces_at_[hidden]> On Behalf
> Of Robin Savonen Söderholm via Std-Proposals
> > Sent: Friday, January 9, 2026 10:36 AM
> > To: C++ Proposals <std-proposals_at_[hidden]>
> > Cc: Robin Savonen Söderholm <robinsavonensoderholm_at_[hidden]>
> > Subject: Re: [std-proposals] resolving function overloading ambiguity
> for bool arguments
> >
> >
> >
> > You already can:
> >
> >
> >
> > void foo(double arg1, std::same_as<bool> auto arg2)...
> >
> >
> >
> > On Fri, Jan 9, 2026, 18:18 David Brown via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> >
> >
> >
> > On 09/01/2026 17:37, Steve Weinrich via Std-Proposals wrote:
> > > Consider two methods:
> > >
> > > void interest (double arg1, bool minor);
> > >
> > > void interest (double arg1, int factor);
> > >
> > > The call: interest(5.5, 5); is ambiguous because 5 will freely convert
> > > to a bool.
> >
> > No, it is not ambiguous - the best fit overload will be used. The rules
> > for overload resolution are a bit complicated, but in this case the
> > results are clear.
> >
> > <https://en.cppreference.com/w/cpp/language/overload_resolution.html>
> >
> > >
> > > I was wondering what y’all would think of narrowing this behavior by
> > > this addition:
> > >
> > > void interest (double arg1, *explicit* bool minor);
> > >
> > > Potentially, this could be applied to all arguments:
> > >
> > > void *explicit* interest (double arg1, bool minor);
> > >
> >
> > To me, a bigger issue is when you /don't/ have overloads :
> >
> >
> > void interest (double arg1, bool minor);
> >
> > In this situation, the implicit conversion of an int to a bool for
> > "interest(5.5, 5)" is likely to be an error on the programmer's side,
> > but it is accepted without question by C++ compilers. To avoid this,
> > some people use "strong bool" types that have much stricter implicit
> > conversions, such as :
> >
> > class Bool {
> > bool v;
> > public :
> > constexpr Bool(bool v) noexcept : v(v) {}
> > Bool(auto v) = delete;
> > explicit constexpr operator bool() const noexcept { return v; }
> > };
> >
> > Then you can declare the function :
> >
> > void interest (double arg1, Bool minor);
> >
> > and use it with a bool type as the second argument, but not with another
> > type that has an implicit conversion to bool.
> >
> > An alternative way to block non-bool calls would be to write :
> >
> > void interest (double arg1, bool minor);
> > void interest (double arg1, auto) = delete;
> >
> >
> > But it would be very nice (IMHO) if you could just write :
> >
> > void interest (double arg1, explicit bool minor);
> >
> > and get the same effect (that is, a function candidate would not be
> > considered "viable" in overload resolution if the second argument
> > required an implicit conversion sequence to the specified type).
> >
> > --
> > Std-Proposals mailing list
> > Std-Proposals_at_[hidden]
> > https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
> >
> > --
> > Std-Proposals mailing list
> > Std-Proposals_at_[hidden]
> > https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2026-01-09 18:00:26
