Preciso colocar constexpr depois do else-if?
Inspirado poresta resposta, Tentei copiar e colar (e adicionar testes nomain()
) este código:
template<typename T>
std::tuple<int, double> foo(T a) {
if constexpr (std::is_same_v<int, T>)
return {a, 0.0};
else if (std::is_same_v<double, T>)
return {0, a};
else
return {0, 0.0};
}
int main()
{
auto [x, y] = foo("");
std::cout << x << " " << y;
}
Isso é muito direto - seT
é deduzido comoint
, queremos retornar uma tupla de[a, 0.0]
. E seT
é deduzido comodouble
, queremos retornar uma tupla de[0, a]
. Caso contrário, queremos retornar[0, 0.0]
.
Como você pode ver, nomain()
função, eu estou chamandofoo
comconst char*
argumento quedevemos resulta emx
ey
ser0
. Isso énão é o caso.
Ao tentar compilá-lo, encontrei um erro estranho:
erro: não foi possível converter '{0, a}
' de '<brace-enclosed initializer list>
' para 'std::tuple<int, double>
'
E eu fiquei tipoo que?. Por que diabos eu iria querer isso ... eu usei especificamentestd::is_same
habilitarreturn {0, a}
só quando o tipo dea
é deduzido comodouble
.
Então eu corri rapidamente paracppreference no if-constexpr. Na parte inferior da página, acimaNotas, podemos ver este trecho de código:
extern int x; // no definition of x required
int f() {
if constexpr (true)
return 0;
else if (x)
return x;
else
return -x;
}
Eu refleti para mim mesmook ..? Eu realmente não consigo ver o que há de errado com o código original. Eles usam a mesma sintaxe e semântica ....
Mas eu estava curioso. Fiquei curioso para saber se algo estranho (naquela época) poderia corrigir esse problema. Alterei o código original para:
template<typename T>
std::tuple<int, double> foo(T a) {
if constexpr (std::is_same_v<int, T>)
return {a, 0.0};
else if constexpr (std::is_same_v<double, T>) // notice the additional constexpr here
return {0, a};
else
return {0, 0.0};
}
int main()
{
auto [x, y] = foo("");
std::cout << x << " " << y;
}
E voilà! O código compilado e executado conforme o esperado. Então, minha pergunta é -Precisamos colocarconstexpr
depois de cadaif
declaração emif-else
declaração neste tipo de situações? Ou é apenas meu compilador? Estou usando o GCC 7.3.