我尝试使用boost::fast_pool_allocator
作为std::list
的分配器,但无法找到使用可变参数模板的construct()
的{{3}}。< / p>
#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)'
查看overload,似乎boost::fast_pool_allocator
只有construct()
的前C ++ 11版本(指针和const_reference)。
请注意,将列表定义为std::list<Pair>
(即使用默认分配器)可以正常工作。
有解决方法吗?任何适配器或某种定义分配器特征的方法?我是分配者的新手,所以这对我来说是一块黑暗的土地。
我可以使用
list.emplace(list.begin(), Pair(1, 2));
但是1)我在生产中使用的实际类比我用于示例的Pair
复杂得多,性能是最重要的(因此我可以真正使用就地构造),并且理想情况下,我希望替换std::allocator
,因此我可以通过单行更改来衡量性能差异。
我在Cygwin中用g ++ 4.9.2和1.58.0进行编译,我在linux环境(RHEL5.5)中使用g ++ 4.8.3和boost 1.55.0时遇到同样的问题。
答案 0 :(得分:2)
outerLoop: for (var i:int = 0; i < 10; i++) {
for (var j:int = 0; j < 10; j++) {
if ( (i == 8) && (j == 0)) {
break outerLoop;
}
trace(10 * i + j);
}
}
/*
1
2
...
79
*/
或某些人。继承自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
,并添加另一个处理varargs的construct
重载。
一个人应该能够写一个&#34;现代化的分配器&#34;我怀疑为你做大部分工作的模板。
construct
上面可能存在拼写错误/错误:它只是解决方案的草图。
答案 1 :(得分:1)
Just for the record, it should be possible to use fast_pool_allocator
directly with a C++11-conforming container, since the container is supposed to use allocator_traits::construct
, which in turn calls the allocator
's construct
only if the call is well-formed ([allocator.traits.members]/p5):
template <class T, class... Args> static void construct(Alloc& a, T* p, Args&&... args);
Effects: calls
a.construct(p, std::forward<Args>(args)...)
if that call is well-formed; otherwise, invokes::new (static_cast<void*>(p)) T(std::forward<Args>(args)...)
.
The problem is that libstdc++'s std::list
is still not conforming to the C++11 standard; it directly calls construct
on the allocator. As a workaround, Yakk's answer is good.