'Return a lambda from a lambda
I want to use a lambda to evaluate (switch-case) some conditions and return a lambda accordingly.
const auto lmb1 = []() {
printf("1\n");
};
const auto lmb2 = []() {
printf("2\n");
};
const auto select = [](auto const &ref) {
switch(ref) {
case 1: return lmb1;
case 2: return lmb2;
}
};
std::function foo = select(1);
foo();
Sadly things aren't working.
What I am doint wrong?
Solution 1:[1]
The problem is that a lambda, by default, deduce (as an auto
function) the returned type and in your lambda you return two different lambdas. Every lambda has a different type, so the compiler can't choose a type for the returned lambda
[](auto const &ref) {
switch(ref) {
case 1: return lmb1; // decltype(lmb1)
case 2: return lmb2; // != decltype(lmb2)
}
};
You can solve the problem in different ways.
You can explicit the lambda returned type, using a type that both
lmb1
andlmb2
can be converted to (in this example,std::function<void()>
or alsovoid(*)()
). When that type is available// -----------------vvvvvvvvvvvvvvvvvvvvvvvv [](auto const &ref) -> std::function<void()> { switch(ref) { case 1: return lmb1; case 2: return lmb2; } };
You can explicitly convert the returned values to a common type. Again: when a common type is available
[](auto const &ref) { switch(ref) { // --V case 1: return +lmb1; // with the '+', lmb1 is converted to a void(*)() case 2: return +lmb2; // with the '+', lmb2 is converted to a void(*)() } // --------------^
If the
ref
argument can be a template value, starting from c++20 you can define a template lambda and, usingif constexpr
, you can return different types from different lambdas. This works also when there isn't a common type (but require a compile-time known argument)const auto selct = []<int REF>(std::integral_constant<int, REF>) { if constexpr ( 1 == REF ) return lmb1; else return lmb2; }; auto foo = selct(std::integral_constant<int, 1>{});
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |