5

次のコードがあります。

#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;
}

次のコマンドラインでコンパイルすると:

clang++ -o test -std=c++11 -stdlib=libc++ test.cpp

次のエラーが表示されます。

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) {

私は自分が信じている問題を理解しています。テンプレートの引数は constexpr である必要がありますが、明らかにそうではありません。問題は、これを機能させるために変更できる可能性があるかどうかです。この作業により、手動で行う以外に、ATYPE の型ごとにこのテンプレート クラスからこれらの静的カウンターをリセットするためのより良い方法が得られる可能性があります。

Object<Undefined>::counter.store(0);
Object<typeA>::counter.store(0);
...

ATYPE に多くの型が含まれている場合、これはそれほどエレガントでも実用的でもありません。

あなたの助けとアドバイスに感謝します。

4

1 に答える 1