我可以使用变量模板声明另一个变量模板



具有可变模板出现在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给出了此(再次,Tint *工作正常):

错误: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()
{
}

最新更新