2014-01-26 130 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() 
{ 
} 
相關問題