是否可以在类中创建非静态模板字段?
如果不是,如何解决?
此类字段应根据需要在编译时创建。
例子
我有很多B
-类,如 B1
, B2
, B3
.
(在实际情况下,它们的名称更有意义。)
我想创建一个类 D
具有非静态 模板函数add<BX>()
必须 counter++
每次我调用每个人BX
,对于 D 的某个实例。
(在实际情况下,它会做一些更复杂的事情。)
这是一个有效的 demo去实现它。
可悲的是,我目前必须对每个 BX
进行硬编码, 一个接一个 ( B1
, B2
, B3
) 在 D
内:-
class B1{};class B2{};class B3{};
class Counter{
public: int counter=0;
};
template<class BX>class Tag{};
class D{
Counter countB1;
Counter countB2;
Counter countB3;
public: template<class BX> void add(){
add_(Tag<BX>());
}
private:
void add_(Tag<B1>){ countB1.counter++;}
void add_(Tag<B2>){ countB2.counter++;}
void add_(Tag<B3>){ countB3.counter++;}
public: template<class BX> int get(){
return get_(Tag<BX>());
}
private:
int get_(Tag<B1>){ return countB1.counter;}
int get_(Tag<B2>){ return countB2.counter;}
int get_(Tag<B3>){ return countB3.counter;}
};
这里是用法。请注意 D
的每个实例保留自己的counter
:-
int main() {
D d1;
d1.add<B2>(); d1.add<B2>(); d1.add<B3>();
std::cout<<d1.get<B1>()<<" "<<d1.get<B2>()<<" "<<d1.get<B3>()<<"\n";
//^ print 0 2 1
D d2;
d2.add<B1>();
std::cout<<d2.get<B1>()<<" "<<d2.get<B2>()<<" "<<d2.get<B3>()<<"\n";
//^ print 1 0 0 (not 1 2 1)
return 0;
}
我梦想着这样的事情:-
class D{
Counter<BX> countBX; //???
public: template<class BX> void add(){
Counter<BX>::getNonStaticInstance(this).counter++; //???
}
public: template<class BX> int get(){
return Counter<BX>::getNonStaticInstance(this).counter; //???
}
};
如果 countBX
我知道怎么做是静态的,但对于非静态来说似乎是不可能的。
最佳答案
你不需要RTTI
来解决这个问题,也不需要std::map
,它们非常昂贵(特别是RTTI)。 Variadic 模板和继承可以为您解决这个问题:
class B1 {}; class B2 {}; class B3 {};
template<typename T>
class Counter {
public:
int counter = 0;
};
template<class... BXs>
class D : public Counter<BXs>... {
public:
template<typename B>
void add() {
Counter<B>::counter++;
}
template<typename B>
int get() {
return Counter<B>::counter;
}
};
这与您实际想要的非常接近(顺便说一句,您走对了路)。
关于c++ - 非静态模板成员 : possible?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44021099/