Can I make lambdas deduce the variant return type?
Asked Answered
T

1

7

This mostly theoretical since I can always spell out the return type, but I wonder if there is a way for me to tell lambda that return type should be union(std::variant) of all returns in lambda body.

#include <iostream>
#include <variant>

struct A{
    int val = 47;
};

struct B {
    float val = 4.7;
};

int main()
{
    for (int i=0;i<8;++i){
                      // can this be something like -> auto_variant  (auto_variant is some library type)
        auto var = []()->std::variant<A, B> {
            if (rand()%2 ){
                return A{};
            } else {
                return B{};
            }
        }();
        std::visit ([](const auto& val) {std::cout<< val.val << std::endl;}, var);
    }
}

note: my strong feeling is that the answer is NO, this is not possible, but I am curious if somebody knows some trick.

note2: using std::any does not fit my requirements, since I want the return type of lambda be known at compile time, instead of at runtime(with any_cast).

Thayer answered 9/2, 2021 at 13:32 Comment(4)
I'm 99.99999% sure this can't be done. You'd need to inspect every return path, and I don't even think reflection could help you there.Pilate
"my strong feeling is that the answer is NO" Same here. I don't see how we can deduce a std::variant<A, B>. Maybe with reflection (But I doubt also we can do that).Homogeneity
If it was possible, why would it deduce to std::variant<A, B> and not std::variant<B, A>?Alumnus
IMPO this is example of overusing lambda. When I'm coding I'm avoiding complex lambdas as much as possible. Complex code I extract to function/method which then lambda uses. With this approach your problem will not exists, since you will have a function which returns std::variant so deduction of return value of lambda is not a problem. Note this is my personal practice which I'm finding quite useful, so if you do not like it do not complain on it.Fret
B
3

You will find I'm cheating but maybe

using A_or_B = std::variant<A, B>;

then

[]() {
  if (rand()%2) {
    return A_or_B{A{}};
  } else {
    return A_or_B{B{}};
  }
}

does the trick?

Benitobenjamen answered 9/2, 2021 at 13:48 Comment(2)
First, this really doesn't automate this, which I beleive is what the OP is looking for. Also, why not use a trailing return type so you don't have to keep repeating A_or_B?Pilate
@Pilate I agree with you (thus my first words...), but I don't know the OP's intention, so why not? (and some complain about posting short answers as comments, that's why I dared posting this answer I find a bit ridiculous...)Benitobenjamen

© 2022 - 2024 — McMap. All rights reserved.