从我在http://en.cppreference.com/w/cpp/memory/allocator中读到的内容来看,分配器的大多数功能现在都将被弃用。问题是,如何在新代码中使用分配器?现在“正确”的方式是什么?
根据我在文档中推断的内容,construct
是分配器特征的一部分,而不是分配器本身。
我正在构建一个自定义容器,这里是构造函数的一个非常简单的版本,这是一个很好的新设计用法吗?
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_, ptr, value);}
);
答案 0 :(得分:5)
是的,目前的方法是通过std::allocator_traits
。您将能够以这种方式支持“最小分配器接口”。
http://en.cppreference.com/w/cpp/concept/Allocator
某些要求是可选的:模板
std::allocator_traits
提供所有可选要求的默认实现,并且所有标准库容器和其他分配器感知类通过std::allocator_traits
访问分配器,而不是直接访问。
如果您观察std::allocator_traits
成员函数和typedef,您将看到他们正在检测是否存在适当的函数/类型,并且如果可以,则通过它们进行调度。
如果您已使用std::allocator_traits
,则弃用和将来可能删除的内容不会发生任何变化,因为它仅适用于std::allocator
及其成员函数/ typedef。
现在,如果你问我,for循环没有问题,并且使用std::for_each
什么也没有获得。有几个uninitialized_*
函数,但它们直接使用placement new。如果您真的在意,可以将此代码提取到单独的construct_range
函数。
还有一个异常安全问题 - 如果其中一个构造函数抛出,你需要销毁前面的元素以满足强大的异常保证并释放内存(析构函数不会在构造函数抛出的情况下被调用)