自定义std :: allocator用于替换operator new的类

时间:2014-09-18 17:50:53

标签: c++ stl new-operator allocator placement-new

我最近使用SSE替换了一些Vector / Matrix类,现在确保内存正确对齐。

根据this question的答案中的建议,我已经为需要它的类替换了operator new / delete,并开始使用自定义分配器来与STL容器一起使用 - 但是,似乎两者之间存在一些冲突:

要开始使用,我只是简单地复制并粘贴了here中的示例分配器类,当我将它与有问题的类型的std :: vector一起使用时,它编译得很好而没有我的自定义新/删除,但当我更换这些功能时,我收到一个错误"没有匹配功能来调用' operator new'"来自construct()函数,

void    construct(pointer p, const T& t)    { new(p) T(t); }

我想我已经取代了#34;平常"新的以某种方式掩盖了新的位置?但是,鉴于我无法编写自己的新位置,我不能确定该做什么......我是新的(NPI)整个自定义内存分配事情,所以任何建议都会非常感激!

我使用Clang v3.4(或gcc 4.1.2)在Linux上进行编译;不使用C ++ 11。

非常感谢。

3 个答案:

答案 0 :(得分:4)

规范allocator::construct来电::new((void *)p) T(val)

通过省略::,您可以让名称查找从T的类范围开始,在此范围内找到您的类范围operator new并且不再继续({1}} {3}}在找到任何匹配名称的第一个范围停止,即使在某个封闭范围内存在更好的候选者)

(转换为void以防万一用户潜入全局几乎放置的新重载,该重载采用非void指针参数)

PS:正如评论中正确指出的那样,“鉴于我不能自己编写新的位置”是错误的假设。您无法替换全局placement-new,但您当然可以编写一个特定于类的placement new,然后通过类范围查找来获取它。查看name lookup以获取有关分配功能的摘要。

答案 1 :(得分:1)

我建议使用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的区别,模板忽略了类型属性,所以我相信它们最终都会使用相同的扩展,这是长期的#34; (或者在非i和d类型的情况下为float / double)。

答案 2 :(得分:0)

我会使用我的起点作为此处给出的分配器:http://en.cppreference.com/w/cpp/concept/Allocator。这实际上是一个最小的分配器。特别是,您根本不需要写constructallocator_traits,如果找不到您的分配器有construct方法,则只需为您调用新的位置,使用::正确确定调用范围(如Cubbi所述),这样您就不会# 39;有这个问题:http://en.cppreference.com/w/cpp/memory/allocator_traits/construct

我可能根本不会写自定义新/删除。只需编写自定义分配器就足够了,让您的Vector / Matrix类使用自定义分配器通过std::vector管理数据。