Detectando constexpr con SFINAE
Estoy trabajando en actualizar un código de C ++ para aprovechar la nueva funcionalidad de C ++ 11. Tengo una clase de rasgos con algunas funciones que devuelven tipos fundamentales que la mayoría de las veces, pero no siempre, devuelven una expresión constante. Me gustaría hacer diferentes cosas en función de si la función esconstexpr
o no. Se me ocurrió el siguiente enfoque:
template<typename Trait>
struct test
{
template<int Value = Trait::f()>
static std::true_type do_call(int){ return std::true_type(); }
static std::false_type do_call(...){ return std::false_type(); }
static bool call(){ return do_call(0); }
};
struct trait
{
static int f(){ return 15; }
};
struct ctrait
{
static constexpr int f(){ return 20; }
};
int main()
{
std::cout << "regular: " << test<trait>::call() << std::endl;
std::cout << "constexpr: " << test<ctrait>::call() << std::endl;
}
El extraint
/...
El parámetro está allí de modo que si ambas funciones están disponibles después deSFINAE, el primero se elige por resolución de sobrecarga.
Compilando y ejecutando esto conClang 3.2 muestra:
regular: 0
constexpr: 1
Parece que esto funciona, pero me gustaría saber si el código es legal C ++ 11. Especialmente porque entiendo que las reglas paraSFINAE han cambiado.