C++ 非类型模板参数不是常量表达式

C++ 非类型模板参数不是常量表达式,c++,templates,c++11,constexpr,clang++,C++,Templates,C++11,Constexpr,Clang++,我有以下代码: #include <cstdlib> #include <cstdio> #include <atomic> enum ATYPE { Undefined = 0, typeA, typeB, typeC }; template<ATYPE TYPE = Undefined> struct Object { Object() { counter++; } static std::atomic<int>

我有以下代码:

#include <cstdlib>
#include <cstdio>
#include <atomic>

enum ATYPE { Undefined = 0, typeA, typeB, typeC };

template<ATYPE TYPE = Undefined>
struct Object
{
    Object() { counter++; }
    static std::atomic<int> counter;
};

template<ATYPE TYPE>
std::atomic<int> Object<TYPE>::counter(1);

template<ATYPE TYPE>
void test()
{
    printf("in test\n");
    Object<TYPE> o;
}

int main(int argc, char **argv)
{
    test<typeA>();
    printf("%d\n", Object<typeA>::counter.load());
    Object<typeA>::counter.store(0);
    for (int i = 0; i < sizeof(ATYPE); ++i) {
        Object<static_cast<ATYPE>(i)>::counter.store(0);
    }
    return 0;
}
我得到以下错误:

test.cpp:32:20: error: non-type template argument is not a constant expression
Object<static_cast<ATYPE>(i)>::counter.store(0);
^~~~~~~~~~~~~~~~~~~~~
test.cpp:32:39: note: read of non-const variable 'i' is not allowed in a constant expression
Object<static_cast<ATYPE>(i)>::counter.store(0);
^
testray.cpp:31:18: note: declared here
for (int i = 0; i < sizeof(ATYPE); ++i) {
test.cpp:32:20:错误:非类型模板参数不是常量表达式
对象::counter.store(0);
^~~~~~~~~~~~~~~~~~~~~
test.cpp:32:39:注意:常量表达式中不允许读取非常量变量“i”
对象::counter.store(0);
^
testray.cpp:31:18:注意:此处声明
对于(int i=0;i
我理解我所认为的问题。模板的参数需要是constexpr,而我显然不是。所以问题是,我能做些什么改变来让这个工作正常。通过这个工作,我的意思是,我能有更好的方法从这个模板类中为ATYPE中的每个类型重置这些静态计数器,而不仅仅是这样做吗手动删除它:

Object<Undefined>::counter.store(0);
Object<typeA>::counter.store(0);
...
Object::counter.store(0);
对象::counter.store(0);
...
当ATYPE包含许多类型时,它就不那么优雅和实用了


非常感谢您的帮助和建议。

对于这类问题,递归通常是一个简单的解决方案:

#include <type_traits>

enum ATYPE { Undefined = 0, typeA, typeB, typeC, ATYPE_END };

void reset_Object_counter(std::integral_constant<ATYPE, ATYPE_END>)
{}

template < ATYPE n = Undefined >
void reset_Object_counter(std::integral_constant<ATYPE, n> p = {})
{
    Object<p>::counter.store(0);
    reset_Object_counter(std::integral_constant<ATYPE,
                                                static_cast<ATYPE>(n+1)>{});
}

无论如何,您的枚举循环错误。
i
也不是一个常量表达式,正如错误显示的那样。@Rapptz,您能更具体地说明您的第一条注释(循环枚举错误)吗.我知道我不是常量,所以这就是为什么我要问是否有某种方法可以让它工作。是否有某种方法可以循环枚举的所有元素并重置计数器?谢谢。Rapptz的意思是我是动态的,不能用作编译时模板参数是的,很好,我现在明白了,因此是message of i是非常量,这是必需的,等等。我明白了。我想知道除了为枚举的每个元素手动操作之外,是否有人可以建议一种技术…?谢谢。@user18490提示:
sizeof(enum)==sizeof(std::底层类型::type)我知道我不知道C++的足够多。我从来没有听说过积分常数。但是我正在追赶我们在C++ 11中发现的所有新事物,看起来它可以花上一生的时间。感谢很多伟大的答案,而且谢谢大家。@代码USE18490[TimealAlgFieldAudio] /代码>这里甚至不需要。实际上,我试图编写代码,因为我猜它可以在没有的情况下工作,但我还是很高兴能学到一些东西。谢谢你的这句话。谢谢你添加了第二个解决方案。我几乎完成了一半,但有你的例子节省了我的时间。再次感谢,非常好的帮助。
#include <type_traits>

enum ATYPE { Undefined = 0, typeA, typeB, typeC, ATYPE_END };

void reset_Object_counter(std::integral_constant<ATYPE, ATYPE_END>)
{}

template < ATYPE n = Undefined >
void reset_Object_counter(std::integral_constant<ATYPE, n> p = {})
{
    Object<p>::counter.store(0);
    reset_Object_counter(std::integral_constant<ATYPE,
                                                static_cast<ATYPE>(n+1)>{});
}
template<>
void reset_Object_counter<ENUM_END>(std::integral_constant<ATYPE, ENUM_END>)
{}
template < ATYPE n = Undefined >
void reset_Object_counter()
{
    Object<n>::counter.store(0);
    reset_Object_counter<static_cast<ATYPE>(n+1)>();
}
template<>
void reset_Object_counter<ENUM_END>()
{}