Могу ли я заставить лямбда-выражения вывести тип возвращаемого значения варианта?

Это в основном теоретически, так как я всегда могу указать тип возвращаемого значения, но мне интересно, есть ли способ указать лямбде, что тип возвращаемого значения должен быть union(std::variant) всех возвратов в теле лямбда.

#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);
    }
}

примечание: у меня сильное ощущение, что ответ НЕТ, это невозможно, но мне любопытно, знает ли кто-нибудь какой-нибудь трюк.

note2: использование std::any не соответствует моим требованиям, так как я хочу, чтобы возвращаемый тип лямбда был известен во время компиляции, а не во время выполнения (с any_cast).


person NoSenseEtAl    schedule 09.02.2021    source источник
comment
Я на 99,99999% уверен, что это невозможно. Вам нужно будет проверить каждый обратный путь, и я даже не думаю, что отражение может помочь вам в этом.   -  person NathanOliver    schedule 09.02.2021
comment
у меня сильное чувство, что ответ НЕТ Здесь то же самое. Я не понимаю, как мы можем вывести std::variant<A, B>. Может быть, с отражением (но я тоже сомневаюсь, что мы можем это сделать).   -  person Jarod42    schedule 09.02.2021
comment
Если бы это было возможно, то почему он вывел бы std::variant<A, B>, а не std::variant<B, A>?   -  person Kevin    schedule 09.02.2021
comment
ИМПО, это пример чрезмерного использования лямбды. Когда я пишу код, я максимально избегаю сложных лямбда-выражений. Сложный код я извлекаю в функцию/метод, который затем использует лямбда. При таком подходе вашей проблемы не будет, так как у вас будет функция, которая возвращает std::variant, поэтому вывод возвращаемого значения лямбда не является проблемой. Обратите внимание, что это моя личная практика, которую я считаю весьма полезной, поэтому, если она вам не нравится, не жалуйтесь на нее.   -  person Marek R    schedule 09.02.2021


Ответы (1)


Вы обнаружите, что я обманываю, но, может быть,

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

тогда

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

трюк?

person prog-fh    schedule 09.02.2021
comment
Во-первых, это действительно не автоматизирует это, и я считаю, что это то, что ищет ОП. Кроме того, почему бы не использовать завершающий возвращаемый тип, чтобы вам не приходилось повторять A_or_B? - person NathanOliver; 09.02.2021
comment
@NathanOliver Я согласен с вами (таким образом, мои первые слова ...), но я не знаю намерений ОП, так почему бы и нет? (и некоторые жалуются на публикацию коротких ответов в виде комментариев, поэтому я осмелился опубликовать этот ответ, который я считаю немного нелепым...) - person prog-fh; 09.02.2021