Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does C++ lambda overloading not behave as expected?

#include <type_traits>

template<typename T, typename... Args_>
concept IsCallable = std::is_invocable_v<T, Args_...>;

struct A
{
    int n = 0;

    void f(IsCallable<int&> auto const fn)
    {
        fn(n);
    }

    void f(IsCallable<int const&> auto const fn) const
    {
        fn(n);
    }
};

struct Lambda
{
    void operator()(auto& n) const
    {
        n = 1;
    }
};

int main()
{
    auto a = A{};
    a.f(Lambda{});               // ok
    a.f([](auto& n) { n = 1; }); // error: assignment of read-only reference 'n'
}

See online demo

Why does C++ lambda overloading not behave as expected?

like image 535
xmllmx Avatar asked May 07 '26 00:05

xmllmx


1 Answers

  1. Your question is nearly a duplicate of Hard error when using std::invoke_result_t with a generic lambda . As with the other question, your code will work the way you expect, if you change the lambda so that it has an explicit -> void return type, thus avoiding return type deduction.
  2. The difference between your question and the other one is that in your question, you're using std::invocable_v rather than std::invoke_result_t. However, the code in this case is still ill-formed because return type deduction is still triggered even though you're not asking for it.
  3. The standard requires is_invocable to determine whether or not the INVOKE expression would be "well-formed when treated as an unevaluated operand". libstdc++ and libc++ both use decltype to create an unevaluated operand for this purpose, so, obviously, return type deduction has to be done. But it seems to me that there is no way to avoid triggering return type deduction, therefore there is no possible standard library implementation that would allow your code to compile (it is not a bug in GCC/Clang).
like image 115
Brian Bi Avatar answered May 09 '26 13:05

Brian Bi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!