Necesito poner constexpr después de else-if?
Inspirado poresta respuesta, Intenté copiar y pegar (y agregar pruebas enmain()
) 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;
}
Esto es muy sencillo, siT
se deduce comoint
, queremos devolver una tupla de[a, 0.0]
. SiT
se deduce comodouble
, queremos devolver una tupla de[0, a]
. De lo contrario, queremos devolver[0, 0.0]
.
Como puedes ver, en elmain()
función, estoy llamando afoo
conconst char*
argumento, quedeberí resulta enx
yy
siendo0
. Es decirno es el cas.
Mientras intentaba compilarlo, encontré un extraño error:
error: no se pudo convertir '{0, a}
' desde '<brace-enclosed initializer list>
' a 'std::tuple<int, double>
'
Y me quede como¿qué. ¿Por qué querría eso? Usé específicamentestd::is_same
para permitirreturn {0, a}
solament cuando el tipo dea
se deduce comodouble
.
Así que rápidamente corrí a cppreference en if-constexpr. En la parte inferior de la página, encima de Notas, podemos ver este fragmento 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;
}
Pensé dentro de míoookay ..? Realmente no puedo ver qué hay de malo con el código original. Usan la misma sintaxis y semántica ....
Pero tenía curiosidad. Tenía curiosidad por saber si algo extraño (en ese momento) podría solucionar ese problema, así que cambié el código original a:
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;
}
¡Y voilá! El código compilado y ejecutado como se esperaba. Entonces, mi pregunta es: ¿Necesitamos ponerconstexpr
después de cadaif
declaración enif-else
declaración en este tipo de situaciones? ¿O es solo mi compilador? Estoy usando GCC 7.3.