Search code examples
c++c++14variable-templates

Can I use a variable template to declare another variable template?


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?


Solution

  • 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.