是否可以根据分配对象的类型特征覆盖全局 new 运算符?
Can the global new operator be overridden based on allocated object's type traits?
我正在尝试升级我们的池固定块内存分配器,以利用c++ 11的类型特征。
目前,可以通过传统方式重写全局new操作符,强制将任何位置的任何对象的任何分配分配到正确的池中,如eg
void* operator new (std::size_t size)
{ // if-cascade just for simplest possible example
if ( size <= 64 ) { return g_BlockPool64.Allocate(); }
else if ( size <= 256 ) { return g_BlockPool256.Allocate(); }
// etc .. else assume arguendo that we know the following will work properly
else return malloc(size);
}
在许多情况下,如果可以根据类型特征(如is_trivially_destructible
)将对象分配到不同的池中,我们可以进一步提高性能。是否有可能使一个模板化的全局new操作符知道分配的类型,而不仅仅是请求的大小?相当于
template<class T>
void *operator new( size_t size)
{
if ( size < 64 )
{ return std::is_trivially_destructible<T>::value ?
g_BlockPool64_A.Allocate() :
g_BlockPool64_B.Allocate(); } // etc
}
在每个类中重写成员new操作符在这里不起作用;我们真的需要它在任何地方的任何分配下都能自动工作。位置new也不能工作:要求每个alloc看起来像
Foo *p = new (mempool<Foo>) Foo();
简短的回答是否定的。分配/释放函数有以下签名:
void* operator new(std::size_t);
void* operator new[](std::size_t);
void operator delete(void*);
void operator delete[](void*);
大多数偏离这些签名将导致您的函数根本不被使用。在一个典型的实现中,你基本上是在链接器级别替换默认的实现——也就是说,现有的函数有一些特定的混乱的名称。如果您提供的函数的名称与相同的结果混淆,则会将其链接起来。如果你的函数没有得到相同的名称,它将不会被链接。
在某些情况下可能会使用您建议的模板,但如果这样做,它将导致未定义的行为。根据您如何安排头文件(例如),您最终可能会将模板的使用与默认函数混合在一起,此时您所希望的最好结果是它快速而干净地崩溃。
相关文章:
- 如何声明特征矩阵,然后通过嵌套循环初始化它
- 使用ios:ate写入到流会覆盖现有文件
- 特征::矩阵<双精度,1,3> 结构类型函数中的返回类型函数
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 我可以重新分配/覆盖std::字符串吗
- 特征命名访问向量段
- 将特征矩阵的向量设置为0
- 特征:模板函数中矩阵的平面图
- 叮叮当当在修复时插入多个"覆盖"说明符
- 谷歌模拟和覆盖关键字
- basic_string的前导/尾部不区分空格的特征
- 特征 3 类的模板专用化
- TMap::Emplace() 在应用现有密钥时会覆盖吗?
- 特征 c++:复矩阵的面积双曲正切(atanh)
- C++ 中的特征向量计算
- 此测试()中发生了什么意外过程?为什么总是覆盖 ch[0 1 2..]?
- 根据C++标准的定义实现"is_similar"类型特征
- C++类型特征,以查看是否可以<uint32_t>对类型"K"的任何变量调用"static_cast(k)"
- 覆盖和扩展数组或矩阵,而不在特征中定义其大小
- 是否可以根据分配对象的类型特征覆盖全局 new 运算符?