Для этого кода:
struct A {};
struct B {};
auto f() -> std::variant<A, B>
{
if (true) return A();
return B();
}
Может ли компилятор автоматически определить возвращаемый тип как std::variant<A,B>
?
Точно так же объявление типа возвращаемого значения можно опустить:
auto f() // std::variant<A, B> deduced by compiler
{
if (true) return A();
return B();
}
Т.е. почему он выбирает std::variant<A, B>
, а не std::variant<A, B, std::monostate>
или boost::variant<A, B>
или std::any
или ...?
Нет, это невозможно.
Автоматический вывод типа возвращаемого значения работает только тогда, когда все операторы you return
возвращают один и тот же тип, а здесь A
и B
разные.
Было бы очень сложно (если не невозможно) определить правила каким-либо другим способом.
В вашем случае, например, могут быть другие типы, которые могут быть созданы либо из A
, либо из B
, например:
std::variant<A, B, std::monostate>
(или любой другой std::variant
, который может содержать A
или B
или любой другой тип).std::any
.Также может быть какой-то собственный класс, у которого есть конструкторы: один принимает A
, а другой принимает B
.
Все эти примеры демонстрируют, почему ожидать, что компилятор выведет variant<A, B>
в качестве возвращаемого типа, — это слишком много.
Я не думаю, что это возможно. Может быть множество типов, которые можно построить из
A
илиB
, которые не являются этимvariant
. И вообще, тип возвращаемого значения можно вывести только в том случае, если все ваши операторыreturn
возвращают один и тот же тип (и здесьA
иB
разные).