从我在文档中推导出来,构造是分配器特征的一部分,而不是分配器本身.
我正在构建一个自定义容器,这里是一个非常简单的构造函数版本,这是一个很好的使用新的设计?
container::container(std::size_t size,T const& value,Allocator const& allocator) : allocator_(allocator){ data_ = std::allocator_traits<Alloc>::allocate(allocator_,size); for(auto ptr = data_; ptr != data_ + size; ++ptr){ std::allocator_traits<Allocator>::construct(allocator_,ptr,value) } }
我试图在循环中使用一个算法(如std :: for_each),但是我没有使用一个没有采用地址(operator&)的方法.
在哪里可以找到现代分配器的完整示例?
经过一些调整,我发现了一种使用算法而不是原始循环(可以传递执行策略)的方法.我不太确定,但可能是这样的:
data_ = std::allocator_traits<Allocator>::allocate(allocator_,size); std::for_each([policy? deduced from allocator?,] boost::make_counting_iterator(data_),boost::make_counting_iterator(data_ + size),[&](auto ptr){std::allocator_traits<Allocator>::construct(allocator_,value);} );
解决方法
http://en.cppreference.com/w/cpp/concept/Allocator
Some requirements are optional: the template
std::allocator_traits
supplies the default implementations for all optional requirements,and all standard library containers and other allocator-aware classes access the allocator throughstd::allocator_traits
,not directly.
如果您观察到std :: allocator_traits成员函数和typedef,您将看到它们正在检测到存在适当的函数/类型,并通过它们进行调度.
如果您已经使用std :: allocator_traits,因为它只适用于std :: allocator及其成员函数/ typedefs,所以弃用和潜在的将来删除将不会改变.
现在,如果你问我,for循环没有什么问题,并且使用std :: for_each没有什么收获.有几个未初始化的*函数,但它们直接使用布局新的.如果你真的关心你可以将这个代码提取到一个单独的construct_range函数.
还有一个异常安全问题 – 如果一个构造函数抛出,你需要销毁早期的元素,以满足强大的异常保证并释放内存(构造函数抛出时不会调用析构函数)