为具有已替换运算符new的类自定义std::分配器
Custom std::allocator for classes with replaced operator new
我最近用使用SSE的类替换了一些Vector/Matrix类,现在正在确保内存正确对齐。
根据这个问题答案中的建议,我已经为需要它的类替换了运算符new/delete,并开始开发一个用于STL容器的自定义分配器——然而,两者之间似乎存在一些冲突:
首先,我只是从这里复制并粘贴了示例分配器类,当我在没有自定义new/delete的情况下将其与所讨论类型的std::vector一起使用时,它会编译得很好,但当我替换这些函数时,我会从construct()函数中得到一个错误"没有匹配的函数可以调用‘operator new’"
void construct(pointer p, const T& t) { new(p) T(t); }
我想我已经取代了"通常"的新位置,这在某种程度上掩盖了新位置?然而,考虑到我不能为它编写自己的新位置,我真的不知道该怎么办……我是整个自定义内存分配的新手,所以任何建议都将不胜感激!
我在Linux上使用Clang v3.4(或gcc 4.1.2)进行编译;不使用C++11。
非常感谢。
规范分配器::construct调用::new((void *)p) T(val)
通过省略::
,您已经让名称查找从T
的类作用域开始,在那里它找到了您的类范围的operator new
,并且不再继续(名称查找停止在找到任何匹配名称的第一个作用域,即使在某些封闭作用域中存在更好的候选者)
(强制转换为void是为了防止用户偷偷进入全局几乎放置的新重载,该重载采用非void指针参数)
附言:正如评论中正确指出的那样,"鉴于我不能写自己的新职位"是错误的假设。您不能替换全局新放置,但您可以编写特定于类的新放置,然后通过类范围查找来获取。有关分配函数的摘要,请查看cppreference。
我建议使用Boost的aligned_allocator:
#include <boost/align/aligned_allocator.hpp>
#include <immintrin.h>
#include <vector>
struct m128i {
// FIXME: ctors/opers with intrinsics would be nice (required?)
__m128i data;
}
int main()
{
std::vector<m128i, boost::alignment::aligned_allocator<m128i, 16> > v;
v.emplace_back();
}
注意:我已经更新了它,使用了一个包装内部成员的结构。有很多图书馆这样做。这样做的原因很简单:vector_size属性将__m128i与__m256i与__m512i区分开来,模板忽略了类型属性,所以我相信它们最终都会使用相同的扩展,即"long-long"(在非I和d类型的情况下,则为float/double)。
我将使用我的起点作为这里给出的分配器:http://en.cppreference.com/w/cpp/concept/Allocator.它实际上是一个最小分配器。特别是,您根本不需要编写construct
。如果allocator_traits
没有发现您的分配器有construct
方法,它只会为您调用placement new,用::
正确地确定调用范围(正如Cubbi所指出的),这样您就不会有这个问题:http://en.cppreference.com/w/cpp/memory/allocator_traits/construct.
我可能根本不会写自定义的新/删除。只需编写一个自定义分配器,并让Vector/Matrix类使用自定义分配器通过std::vector
管理它们的数据就足够了。
- 如何比较自定义类的std::变体
- std::设置自定义比较器
- std::ranges::elements_view,用于自定义类似元组的数据
- 使用自定义比较函数使用std::sort()对矢量字符串进行排序时出现问题
- 在自定义 std::vector-like 容器中处理指针和非指针模板类型的最佳方法是什么?
- 自定义 std::fstream,std::filebuf 的溢出和下溢函数未为每个字符调用
- 运算符的歧义错误<<自定义 std::ostream 子类中的重载
- 自定义 std::shared_ptr 删除器
- 自定义 std::shared_ptr 或 boost::shared_ptr 以在 NULL 取消引用时引发异常
- 如何在自定义 std::ostream 类中使用 std::endl
- 如何实现自定义 std::streambuf 的 seekoff()?
- 如何使用自定义std::sort函数
- 为具有已替换运算符new的类自定义std::分配器
- 使用函数指针自定义std::设置比较器
- 自定义std::binary_search的比较函数
- 自定义std::set比较函数的参数
- 创建自定义std流实现时的编译器警告
- 无法捕获自定义std::runtime_error
- C++ 自定义 std::map<>导致内存冲突的键类
- 如何在c++中实现自定义std集合