C++ - 从客户端代码中隐藏模板参数
Posted
技术标签:
【中文标题】C++ - 从客户端代码中隐藏模板参数【英文标题】:C++ - Hiding template parameters from client code 【发布时间】:2014-01-30 18:36:02 【问题描述】:我最近一直在阅读有关 c++ 的自定义内存分配器的内容,并遇到了一个有趣的概念,在该概念中,使用实际上是指向指针的指针“句柄”而不是使用指针,这允许分配器重新排列其内存以避免碎片,同时避免使所有指向已分配内存的指针无效的问题。
但是,不同的分配器可能希望以不同的方式使用句柄,例如,池分配器不需要重新排列其内存,就像其他分配器一样。那些需要重新排列内存的人可能需要将句柄视为指向指针的指针、指向指针数组的索引等,而不重新排列内存的分配器会将句柄视为简单的指针。理想情况下,每个分配器都能够使用不同类型的句柄,以便获得最佳性能,具有虚拟方法的基句柄类会产生大量开销,因为每次需要访问任何函数/成员时都会使用句柄动态分配的类。
我的解决方案是使用部分模板特化,以便在编译时确定句柄类型,消除虚拟的运行时开销并允许编译器进行其他优化(例如:内联)
/////////////////////////////////////////////////
/// \brief The basic handle class, acts as simple pointer
/// Single layer of indirection
/////////////////////////////////////////////////
template <typename T>
class Handle
public:
T* operator->()return obj;
//other methods...
private:
T* obj;
;
/////////////////////////////////////////////////
/// \brief Pointer specialization of the handle class, acts as a pointer to pointer
/// allowing allocators to rearrange their data
/////////////////////////////////////////////////
template <typename T>
class Handle<T *>
public:
T* operator->()return *obj;;
//other methods...
private:
T** obj;
;
这完美地工作并且允许分配器返回他们需要的任何句柄类型,但是这意味着需要将句柄作为参数的任何函数都需要重载以接受这两种类型的特化,也是一个持有句柄的类需要对成员进行模板化,以确定它是否具有普通句柄、指向指针句柄的指针或其他类型。
当添加更多句柄类型或函数需要多个句柄并且必须为句柄类型的所有组合提供重载时,此问题只会变得更糟。
要么我需要能够使所有指向“TypeA”实例的句柄都具有类型Handle<TypeA>
,然后使用不同的方法来模板专业化以提供不同的功能,或者以某种方式隐藏模板参数。使用句柄的代码。这是如何实现的?
(这种隐藏模板参数的方法在其他情况下也很有用,例如在policy based logging system 中,一个类可能希望持有对任何类型的记录器的引用,而无需对其自身进行模板化。显然在记录的情况下虚拟继承可以用作速度的主要因素是 I/O 而不是函数调用开销)
【问题讨论】:
C++ 分配器模型从未完成,现在作为内存模型永久无用。它仅用于不同的内存分配策略。但是手柄的东西实际上不起作用。 :( 抱歉。 en.wikipedia.org/wiki/Allocator_(C%2B%2B) "...原本打算分配器完全封装内存模型,标准委员会意识到这种方法会导致不可接受的效率下降。为了解决这个问题,在分配器中添加了额外的措辞特别是,容器实现可能假设分配器对指针和相关整数类型的类型定义与默认分配器提供的类型定义等价,并且...实际上与分配器的原始设计目标相矛盾...” 处理你的问题的通常方法是在参数类型上制作函数模板,这样人们就可以通过 Handle, or
T*`。我已经实现了一个完全允许您描述的内存系统,但想不出没有虚拟函数的唯一句柄类型的方法。模板参数是类型的一部分。
最后我做了一个单句柄类型,并使用指针的最低有效位来存储它是直接指针还是间接指针。在取消引用之前,我会检查该位,如果未设置,我将简单地返回指针,否则我将取消设置该位并向内存系统询问实际的指针。
该方案确实有效,但我最终从我的内存系统中删除了间接内存句柄支持,因为我发现开销可能相当高,而且它对我的代码的各个方面都非常具有侵入性。基本上几乎在所有通常会使用指针的地方,我都必须使用句柄。它还需要在用于其他线程之前锁定内存,以便在使用时不会对其进行碎片整理。最后,它要求我编写完全自定义的容器以获得可接受的性能。例如,我不想在循环中对向量的每次访问都进行双重间接。
【讨论】:
以上是关于C++ - 从客户端代码中隐藏模板参数的主要内容,如果未能解决你的问题,请参考以下文章