En el siguiente ejemplo de código, la ifinstrucción depende del boolparámetro de plantilla, que es una constante en tiempo de compilación. Los compiladores manejan este código de manera diferente:
MSVC falla con el error de enlace (que es lo que esperaba), porque la función de plantilla en la
elserama carece de especialización para eltruevalor del parámetro de plantilla (aunque nunca se llama).GCC y Clang compilan sin problemas y el comportamiento en tiempo de ejecución es correcto. Obviamente, esto se debe a que evalúan la
ifdeclaración en tiempo de compilación y eliminan las ramas no utilizadas antes de vincular.
La pregunta es qué comportamiento cumple con los estándares (o es un comportamiento indefinido y ambos son correctos a su manera).
#include <iostream>
template<const bool condition>
struct Struct
{
void print()
{
if (condition)
{
std::cout << "True\n";
}
else
{
printIfFalse();
}
}
private:
void printIfFalse();
};
template <>
void Struct<false>::printIfFalse()
{
std::cout << "False\n";
}
int main()
{
Struct<true> withTrue{};
withTrue.print();
Struct<false> withFalse{};
withFalse.print();
return 0;
}
fuente

if constexprRespuestas:
Todos los compiladores se comportan correctamente.
Su programa es mal formado, no se requiere diagnóstico , porque usted está usando odr a
Struct<true>::printIfFalsetravés de la instanciación deStruct<true>::print()requerido desde la llamadawithTrue.print();. Una función que se usa fuera de una declaración descartada debe tener una definición en el programa, consulte [basic.def.odr] / 4 ; de lo contrario, el programa está mal formado, no se requiere diagnóstico .UNA declaración descartada es lo que obtienes si la usas
if constexpren una plantilla y la declaración no está en la rama elegida. Entonces, lo que puede hacer para que el programa esté bien formado es usarlo enif constexprlugar de hacerloif. Esta es una característica de C ++ 17.fuente