除了此处的其他讨论之外,可能值得注意的是,您可以具有全局性,而不会将用法限制为一个实例。例如,考虑引用计数的情况...
struct Store{
std::array<Something, 1024> data;
size_t get(size_t idx){ /* ... */ }
void incr_ref(size_t idx){ /* ... */}
void decr_ref(size_t idx){ /* ... */}
};
template<Store* store_p>
struct ItemRef{
size_t idx;
auto get(){ return store_p->get(idx); };
ItemRef() { store_p->incr_ref(idx); };
~ItemRef() { store_p->decr_ref(idx); };
};
Store store1_g;
Store store2_g; // we don't restrict the number of global Store instances
现在,main
您可以在函数中的某处(例如)执行以下操作:
auto ref1_a = ItemRef<&store1_g>(101);
auto ref2_a = ItemRef<&store2_g>(201);
ref不需要存储指向它们各自的指针,Store
因为该信息是在编译时提供的。您也不必担心Store
的生存期,因为编译器要求它是全局的。如果确实只有一个实例,Store
那么这种方法就没有开销。对于一个以上的实例,取决于编译器对代码生成的明智程度。如果有必要,ItemRef
类甚至可以做了friend
的Store
(你可以有模板的朋友!)。
如果Store
本身是模板类,则情况会变得更混乱,但仍然可以使用此方法,也许可以通过实现具有以下签名的帮助器类:
template <typename Store_t, Store_t* store_p>
struct StoreWrapper{ /* stuff to access store_p, e.g. methods returning
instances of ItemRef<Store_t, store_p>. */ };
用户现在可以StoreWrapper
为每个全局Store
实例创建一个类型(和全局实例),并始终通过其包装实例访问商店(从而无需使用模板参数的繁琐细节Store
)。