使 boost::fast_pool_allocator 使用可变参数模板(放置)
Making boost::fast_pool_allocator work with variadic templates (emplace)
我试图使用boost::fast_pool_allocator
作为std::list
的分配器,但它找不到使用可变参数模板的construct()
的重载。
#include <list>
#include <utility>
#include <boost/pool/pool_alloc.hpp>
int main()
{
typedef std::pair<int, int> Pair;
std::list<Pair, boost::fast_pool_allocator<Pair>> list;
list.emplace(list.begin(), 1, 2);
}
这无法编译,并显示以下错误(缩短):
stl_list.h:514:8: error: no matching function for call to ‘boost::fast_pool_allocator<blah>::construct(std::list<bleh>::_Node*&, int, int)'
查看头文件,似乎boost::fast_pool_allocator
只有 C++11 之前的construct()
版本(指针和const_reference)。
请注意,将列表定义为std::list<Pair>
(即使用默认分配器)工作正常。
有解决方法吗?任何适配器或某种定义分配器特征的方法?我是分配器的新手,所以这对我来说是一个黑暗的土地。
我可以让它工作
list.emplace(list.begin(), Pair(1, 2));
但是 1st) 我在生产中使用的实际类比我用于示例Pair
要复杂得多,并且性能至关重要(所以我可以真正使用就地构造),以及 2nd) 理想情况下,我希望有一个直接替代品来替代std::allocator
,所以我可以通过一行更改来衡量性能差异。
我正在使用g ++ 4.9.2和boost 1.58.0在Cygwin中进行编译,并且在使用g ++ 4.8.3和boost 1.55.0的linux环境(RHEL5.5)中遇到了同样的问题。
template <typename T,
typename UserAllocator,
typename Mutex,
unsigned NextSize,
unsigned MaxSize >
struct my_pool_allocator:
boost::pool_allocator<T,UserAllocator,Mutex,NextSize,MaxSize>
{
using base=boost::pool_allocator<T,UserAllocator,Mutex,NextSize,MaxSize>;
using base::base;
template <typename U>
struct rebind
{
using other=my_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize>;
};
using base::construct;
template<class...Args>
void construct(const typename base::pointer ptr, Args&&...args)
{ new (ptr) T(std::forward<Args>(args)...); }
};
或诸如此类。 从fast_pool_allocator
继承,继承其构造函数,编写自定义rebind
,继承construct
,并添加另一个处理 varargs 的重载construct
。
我怀疑应该能够编写一个"现代化分配器"模板,该模板可以为您完成大部分工作。
template <class OldAllocator>
struct modernize_allocator:
OldAllocator
{
using base=OldAllocator;
using T=typename base::value_type;
using base::base;
template <typename U>
struct rebind
{
using other=modernize_allocator<typename base::rebind<U>::other>;
};
using base::construct;
template<class...Args>
void construct(const typename base::pointer ptr, Args&&...args)
{ new (ptr) T(std::forward<Args>(args)...); }
};
上面可能有错别字/错误:它只是一个解决方案的草图。
只是为了记录,应该可以直接将fast_pool_allocator
与符合 C++11 的容器一起使用,因为容器应该使用allocator_traits::construct
,而 只有在调用格式正确的情况下才会调用allocator
的construct
([allocator.traits.members]/p5):
template <class T, class... Args> static void construct(Alloc& a, T* p, Args&&... args);
效果:如果调用格式正确,则
a.construct(p, std::forward<Args>(args)...)
调用;否则,调用::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)
。
问题是libstdc++的std::list
仍然不符合C++11标准;它直接在分配器上调用construct
。作为一种解决方法,Yakk的答案很好。
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- C++如何在 switch 语句中放置两个参数
- 我可以在哪里放置参数的默认值
- 为什么在参数输入之前将计算放置在代码中时,计算不起作用
- 为什么聚合结构可以大括号初始化,但不能使用与大括号初始化中相同的参数列表进行放置?
- 使 boost::fast_pool_allocator 使用可变参数模板(放置)
- c++只允许在argv[1]中放置某些参数
- 在 boost::bind 中指定参数放置器后,为什么在调用它时省略它
- 模板化函数和放置新构造函数参数
- 如何将没有构造函数参数的对象放置到STL容器中
- 将构造函数参数转发给放置new操作符
- 在Qt的插槽中放置参数
- c++无序映射放置无效参数
- if语句-if/else和参数放置C++