Я работаю над обновлением кода на С++, чтобы воспользоваться преимуществами новой функциональности на С++ 11. У меня есть класс признаков с несколькими функциями, возвращающими основные типы, которые большую часть времени, но не всегда, возвращают постоянное выражение. Я хотел бы делать разные вещи в зависимости от того, является ли функция constexpr
или нет. Я придумал следующий подход:
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;
}
Дополнительный параметр int
/...
существует, так что если обе функции доступны после SFINAE, первый выбирается путем перегрузки разрешения.
Компиляция и запуск этого с помощью Clang 3.2 показывает:
regular: 0
constexpr: 1
Итак, это работает, но я хотел бы знать, является ли код законным С++ 11. Специально, поскольку я понимаю, что правила для SFINAE изменились.