具有可变模板出现在C 14中(并且已经支持它们),以及标准is_same_v
和同样类型特征的建议,我认为能够如下以下新的类型特征整洁:
template<typename T>
constexpr bool is_const_and_volatile{std::is_const_v<T> && std::is_volatile_v<T>};
a,这会导致与以下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>
具有内部链接,但未定义
它看起来对我定义(请注意,foo
中的T
更改为int *
的工作正常)。将main
中的线插入实例化foo
给出了此(再次,T
至int *
工作正常):
错误:Constexpr变量
初始化foo<int *>
必须通过常数表达式
但是,用以下旧语法替换foo
会导致两个实例正常工作:
constexpr bool foo{std::is_pointer<T>::value};
关于变量模板,我是否缺少一些东西?有没有一种方法可以使用构建新的变量模板,或者我被迫使用较旧的语法来构建新的语法,并且只能在将它们用于其他代码时享受句法糖?
<</p>您的代码有效,并且被Clang SVN接受。链接错误是由Clang Bug 17846引起的,我几天前修复了该错误。
以下似乎有效:
#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*>;
}
实例示例
尽管在 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()
{
}