sentencia resueltos que programacion lenguaje funciona else ejercicios ejemplos condiciones como c++ if-statement c++17 if-constexpr

c++ - resueltos - ¿Necesito poner constexpr después de else-if?



sentencia if else en c++ (1)

¿Necesitamos poner constexpr después de cada sentencia if en el bloque if-else en este tipo de situaciones?

Sí. El else-if bloque 1 es una mentira :), solo hay bloques si 1 y else bloques 1 . Así es como el compilador ve tu código:

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}; // }

else if (/*...*/) es solo una convención de formato que todos usan. Como tal, puede ver claramente que se necesita el segundo constexpr .

1 : "bloque" no es la terminología correcta. si es una declaración (con otra parte opcional). Un bloque es { /*...*/ } .

Inspirado por esta respuesta , intenté copiar y pegar (y agregar pruebas en main() ) 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: si T se deduce como int , queremos devolver una tupla de [a, 0.0] . Si T se deduce como double , queremos devolver una tupla de [0, a] . De lo contrario, queremos devolver [0, 0.0] .

Como puede ver, en la función main() , estoy llamando a foo con el argumento const char* , lo que debería resultar en que x e y sean 0 . Ese no es el caso .

Al intentar compilarlo, me encontré con un error extraño:

error: no se pudo convertir '' {0, a} '' de '' <brace-enclosed initializer list> '' ''a'' std::tuple<int, double> ''

¿Y yo estaba como qué? . Por qué demonios querría que ... std::is_same específicamente std::is_same para habilitar la return {0, a} solo cuando el tipo de a se deduce como double .

Así que rápidamente corrí a cppreference en if-constexpr. En la parte inferior de la página, arriba 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é para mí oookay ..? Realmente no puedo ver lo que está mal con el código original. Utilizan la misma sintaxis y semántica ....

Pero yo tenía curiosidad. Tenía curiosidad si tal vez algo extraño (en ese momento) pudiera 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 espera. Entonces, mi pregunta es: ¿debemos poner constexpr después de cada sentencia if-else en la sentencia if-else en este tipo de situaciones? ¿O es sólo mi compilador? Estoy usando GCC 7.3.