0

Boiled down example of what I wanted to do:

auto callable = [](auto x, auto y = 0){return x + y;};

On it's own it compiles, and callable(1, 2) works as expected, but callable(3) gives a compilation error:

error: no match for call to '(f()::<lambda(auto:1, auto:2)>) (int)'

This is not an issue with lambdas specifically, same thing happens with generic functions with default argument
If callable was a function (template), then callable<int, int>(3) would work
For lambdas this workaround becomes a bit uglier:
callable.operator()<int, int>(3)

What I originally thought would happen under the hood:

struct Callable {
    auto operator()(auto x, auto y){return x + y;}
    auto operator()(auto x){return this->operator()(x, 0);}
};

As in, I was expecting the lambda to behave like Callable{}
And Callable callable; is nice regarding the mentioned behaviour, both callable(1, 2) and callable(3) compile
This "unraveled" lambda-esque struct solution could work for my case, but I have some issues with it:

  1. My actual use for this is significantly more complicated than the boiled down example, and trying to use the struct solution would be a PITA
  2. I'm using C++20, the solution doesn't feel very modern, aesthetically it reminds me of emulating C++20 functionalities in C++11

To sum this up:

  1. I want an object callable
  2. I want the expression callable(a, b) to compile to user-specified implementation
    In the example above the implementation was return a + b; but I obviously don't care about addition specifically
  3. callable(a, b) should be generic, meaning it should be invokable with various types of arguments (as long as the user-specified implementation permits it)
  4. I want the expression callable(a) to compile and to be equivalent to callable(a, 0)
  5. callable(a) should again be generic
  6. I STRONGLY prefer solutions in which callable is a lambda

If I remove the requirements (4) and (5) this is trivially doable with a lambda

All examples mentioned on godbolt

NOTE: default arguments with lambdas work if they aren't generic [](int x, int y = 0){return x+y;}

Tried generic lambda, didn't work
Tried generic function, didn't work
Tried unrolled lambda via struct, works but not that great

Ivan Lazaric
  • 41
  • 1
  • 4

0 Answers0