With variable templates coming in C++14 (and Clang already supporting them) and a proposal for standard is_same_v
and likewise type traits, I figured being able to make new type traits as follows would be neat:
template<typename T>
constexpr bool is_const_and_volatile{std::is_const_v<T> && std::is_volatile_v<T>};
Alas, this results in errors equivalent to the following SSCCE (this one contains everything mentioned below):
#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 *>;
}
With the line in main
commented, Clang spits out the following:
warning: variable
is_pointer<type-parameter-0-0>
has internal linkage but is not defined
It looks defined to me (note that changing T
to int *
in foo
works fine). Uncommenting the line in main
to instantiate foo
gives this (again, T
to int *
works fine):
error: constexpr variable
foo<int *>
must be initialized by a constant expression
However, replacing foo
with the following old syntax causes both instances to work fine:
constexpr bool foo{std::is_pointer<T>::value};
Is there something I'm missing about variable templates? Is there a way to build new variable templates with them, or am I forced to use the older syntax to build new ones and only enjoy the syntactic sugar when using them for other code?
Your code is valid, and is accepted by clang SVN. The link error was caused by clang bug 17846, which I fixed a couple of days ago.