No exemplo de código a seguir, a if
instrução depende do bool
parâmetro do modelo, que é uma constante em tempo de compilação. Os compiladores manipulam esse código de maneira diferente:
MSVC falha com erro de link (o que eu esperava), porque a função de modelo na
else
ramificação não possui especialização para otrue
valor do parâmetro de modelo (mesmo que nunca seja chamado).O GCC e o Clang são compilados sem problemas e o comportamento em tempo de execução está correto. Obviamente, isso ocorre porque eles avaliam a
if
instrução no tempo de compilação e removem ramificações não utilizadas antes da vinculação.
A questão é qual comportamento é compatível com o padrão (ou é um comportamento indefinido e ambos estão corretos à sua maneira)?
#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;
}
if constexpr