我的池分配器有一个内部类Block,它是这样的:
template<class T> PoolAlloc{
...
struct Block{
T userData;
RefCounting rc;
};
Block * m_pPool;
...
};我不知道如何以一种优雅的方式使重新计数成为可选的。将外部块作为额外的模板参数传递是很难看的,因为我必须将T参数同时提供给分配器和分配器参数:
PoolAlloc<Foo, Block<Foo>>这是多余的。我试着只专门化内部结构,但我认为这不是一个选择,内部类需要整个外部类专门化:
template<class T, bool refCounting> PoolAlloc{
...
struct Block;
...
};
template <class T, bool RC> struct PoolAlloc<T,RC>::Block{ T userData; RefCounting rc;};// default
template<class T> struct PoolAlloc<T, false>::Block{ T userData;}; // cant get this to compile发布于 2020-02-05 04:25:24
答案很可能比你想象的要简单。
假设你有struct/class,并且你想让其中的某些东西成为可选的(也就是有没有),这就是“策略”,因为没有更好的词了。您需要做的第一件事是定义两个结构,一个使用实际实现,另一个使用空实现,然后根据需要实例化它。没有其他方法来实现这个BTW,所以你只能在这里使用一些冗余。(默认的template参数和template using在这里可以帮助减少一点冗余。)
例如(未测试):
struct empty_ref_counter {
//empty reference counter implementation
void add_reference() {} // <-- no implementation!!
//other empty member functions
};
struct ref_counter {
//reference counter implmentation
unsigned ref;
void add_reference() {
++ref;
}
//other complete member functions
};
template<typename RefCountPolicy = empty_ref_counter>
struct strA {
typedef typename RefCountPolicy ref_policy;
RefCountPolicy count;
};注意,我做了一个ref_policy的typedef typename,这是strA使用的引用策略,可以用来检查外部来源的ref_policy (也就是接受strA<RCP>的函数)。
换句话说,您可以将Block设置为template struct,并且仍然可以访问外部template class/struct中的T。
struct BlockBase {};
template<typename RefCount>
struct Block : BlockBase {
T userData;
RefCount rc;
};
BlockBase* m_pPool;为了做到这一点,给Block一个非模板库也可能是一个好主意(甚至可以使用虚拟析构函数来确保RefCount被正确地析构!)
https://stackoverflow.com/questions/60064805
复制相似问题