2014-01-26 133 views
8

随着可变模板C++ 14来(和锵已经支持他们)和标准is_same_v的建议,同样类型的特质,我想能够做出新的类型特点如下是整齐:我可以使用变量模板来声明另一个变量模板吗?

template<typename T> 
constexpr bool is_const_and_volatile{std::is_const_v<T> && std::is_volatile_v<T>}; 

唉,这导致等同于以下SSCCE错误(this one包含下面提到的所有内容):

#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行,锵吐出来的是以下几点:

warning: variable is_pointer<type-parameter-0-0> has internal linkage but is not defined

看样子定义为我的(注意,在foo改变Tint *正常工作)。取消注释行main实例foo给出了这样的(再次,Tint *正常工作):

error: constexpr variable foo<int *> must be initialized by a constant expression

然而,下面的旧语法替换foo导致这两种情况下,以优良的工作:

constexpr bool foo{std::is_pointer<T>::value}; 

有什么我失踪的变量模板?有没有办法建立新的变量模板他们,还是我不得不使用旧的语法来建立新的,只享受其他代码时使用它们的语法糖?

+2

你试过显式实例吗? Luc Danton发现了[最近与隐式实例化有关的bug](http://stackoverflow.com/a/21234048/420683) – dyp

+0

(似乎是“工作”,具有明确的实例化:http://coliru.stacked-crooked。 com/a/e16d249679a71d0c) – dyp

+0

@dyp,好的,但是在你的例子中为'bool *'添加一个[仍然给链接器错误](http://coliru.stacked-crooked.com/a/990bc676207518a2),不幸的是,更不用说我不可能为每种类型明确地实例化它。 – chris

回答

0

以下似乎工作:

#include <type_traits> 
#include <iostream> 

template<typename T> 
struct test { 
    static constexpr bool is_pointer{std::is_pointer<T>::value}; 
}; 

template<typename T> 
constexpr bool test<T>::is_pointer; 

template<typename T> 
constexpr bool foo{test<T>::is_pointer}; 

int main() { 
    std::cout << foo<bool>; 
    std::cout << foo<bool*>; 
} 

Live Example

虽然如果在一个constexpr上下文中使用,所以我想它并没有真正的工作毕竟它的特效同样的警告。

// Fail 
template<typename T> 
typename std::enable_if<foo<T>, void>::type bar() 
{ 
} 

int main() { 
    bar<bool*>(); 
} 

main.cpp:21:5: error: no matching function for call to 'bar' 

    bar<bool*>(); 

    ^~~~~~~~~~ 

main.cpp:16:45: note: candidate template ignored: substitution failure [with T = bool *]: non-type template argument is not a constant expression 

typename std::enable_if<foo<T>, void>::type bar() 

如果你给foo一个明确的类型它不会停止抱怨:

template<typename T> 
typename std::enable_if<foo<bool*>, void>::type bar() 
{ 
} 

,或直接使用test<T>::is_pointer

template<typename T> 
typename std::enable_if<test<T>::is_pointer, void>::type bar() 
{ 
} 
相关问题