С появлением шаблонов переменных в C++14 (и Clang их уже поддерживает) и предложением стандарта is_same_v
, а также трейтов типов, я решил, что возможность создавать новые трейты типов следующим образом будет изящной:
template<typename T>
constexpr bool is_const_and_volatile{std::is_const_v<T> && std::is_volatile_v<T>};
Увы, это приводит к ошибкам, эквивалентным следующему SSCCE (в этом содержится все, что указано ниже):
#include <type_traits>
template<typename T>
constexpr bool is_pointer{std::is_pointer<T>::value};
template<typename T>
constexpr bool foo{is_pointer<T>};
int main() {
//foo<int *>;
}
Закомментировав строку в main
, Clang выдает следующее:
предупреждение: переменная
is_pointer<type-parameter-0-0>
имеет внутреннюю связь, но не определена
Для меня это выглядит определенным (обратите внимание, что изменение T
на int *
в foo
работает нормально). Раскомментирование строки в main
для создания экземпляра foo
дает следующее (опять же, от T
до int *
работает нормально):
ошибка: переменная constexpr
foo<int *>
должна быть инициализирована константным выражением
Однако замена foo
на следующий старый синтаксис приводит к тому, что оба экземпляра работают нормально:
constexpr bool foo{std::is_pointer<T>::value};
Есть ли что-то, что мне не хватает в шаблонах переменных? Есть ли способ создавать новые шаблоны переменных с с их помощью, или я вынужден использовать старый синтаксис для создания новых и наслаждаться синтаксическим сахаром только при использовании их для другого кода?
bool *
в вашем примере все равно выдает ошибку компоновщика , к сожалению, не говоря уже о том, что я не могу явно создать экземпляр для каждого типа. - person chris   schedule 26.01.2014is_pointer
не определен. И, конечно же, это предназначено только для того, чтобы показать, что существует связь с неявным созданием экземпляров, а не как решение. - person dyp   schedule 26.01.2014