Como posso especificar o tipo de retorno de uma função com um auto
tipo de retorno inferido ( ), quando o corpo contém várias if constexpr
ramificações e uma delas lança incondicionalmente?
O tipo de retorno deve satisfazer um certo conceito; não posso simplesmente deixá-lo como void
.
Tentei usar, std::declval
mas o g++ static me afirma com "você não pode usar declval".
A questão é: existe alguma abordagem melhor para declarar um tipo de retorno do que um retorno falso?
auto func()
{
if constexpr (A)
{
if (...) return std::vector<int>{}; // actually something difficult to initialize
}
if constexpr (A && C)
{
throw 5;
// fake return to declare return type - same type as if constexpr (A) above
// return std::move(std::declval<std::vector<int>>()); // static assert in std library
return std::move(*static_cast<std::vector<int>*>(nullptr)); // it works! is there any better way?
}
else return std::array<double, 5>{};
}
Embora eu diga que a premissa é instável, você pode criar uma solução para ela com a ajuda de um lambda imediatamente invocado.
O lambda é válido (embora arcano), já que seu corpo nunca flui realmente do fim para causar comportamento indefinido. E o tipo de retorno explícito dá à expressão inteira o tipo que desejamos deduzir na declaração return.
Você também pode transformar isso em um modelo auxiliar, conforme sugerido nos comentários da sua pergunta.