Ho il seguente codice:non di tipo argomento di un template non è un'espressione costante
#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;
}
Quando compilo con la seguente riga di comando:
clang++ -o test -std=c++11 -stdlib=libc++ test.cpp
Ottengo i seguenti errori:
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) {
Capisco il problema in cui credo. L'argomento del modello deve essere un constexpr e chiaramente non lo è. Quindi la domanda è, sono possibili modifiche che posso fare per farlo funzionare. Con questo lavoro, voglio dire, posso in qualche modo avere un modo migliore di reimpostare questi contatori statici da questa classe modello per ogni tipo in ATYPE, diversi dal semplice farlo manualmente:
Object<Undefined>::counter.store(0);
Object<typeA>::counter.store(0);
...
che non è così elegante e pratico quando ATYPE contiene molti tipi.
Grazie mille per il vostro aiuto e consigli.
In ogni caso, stai scorrendo il tuo enum. 'i' non è un'espressione costante neanche come mostra l'errore. – Rapptz
@Rapptz, potresti per favore essere più specifico sul tuo primo commento (scorrendo l'enum sbagliato). So che non sono const, quindi è per questo che sto chiedendo se c'è un modo per farlo funzionare. C'è un modo per aggirare tutti gli elementi dell'enumerazione e azzerare i contatori? grazie. – user18490
Ciò che Rapptz significa è che i è dinamico e non può essere usato come argomento del modello di compilazione tempo –