为什么在shared_ptr没有allocate_unique的unique_ptr情况下有allocate_shared?
我想使用自己的分配器创建一个unique_ptr:我是否必须自己分配缓冲区然后将其分配给unique_ptr?
这似乎是一个明显的成语.
Mik*_*our 16
为什么
shared_ptr有allocate_shared而unique_ptr没有allocate_unique?
shared_ptr需要它,以便它可以使用分配器分配其内部共享状态(引用计数和删除)以及共享对象.unique_ptr只管理对象; 所以不需要为自己提供分配器unique_ptr,也不需要allocate功能.
(make_unique由于同样的原因也没有必要,这可能是为什么它没有在C++ 11中出现的原因,但为了一致性而被大众需求添加到C++ 14中.也许相同的需求会增加allocate_unique未来的标准.)
我是否必须自己分配缓冲区然后将其分配给unique_ptr?
是.或者你可以写自己的allocate_unique; 不同的是allocate_shared,将它与unique_ptr自身分开实施是可能的,而且相当简单.(正如评论中所提到的,你必须确保它为分配器使用了一个合适的删除器;默认的删除器将使用delete并且可怕的错误).
这似乎是一个明显的成语.
确实.但许多其他成语也是如此,并非所有事物都可以(或应该)标准化.
有关目前缺乏的更正式的理由allocate_unique,请参阅提案make_unique,特别是第4节(自定义删除器).
Jon*_*ely 16
我是否必须自己分配缓冲区然后将其分配给unique_ptr?
不只是一个缓冲区,一个指向对象的指针.但是对象可能需要被分配器破坏,内存肯定需要由分配器解除分配,所以你还需要传递分配器unique_ptr.它不知道如何使用分配器,因此您需要将其包装在自定义删除器中,并且它将成为该unique_ptr类型的一部分.
我认为通用解决方案看起来像这样:
#include <memory>
template<typename Alloc>
struct alloc_deleter
{
alloc_deleter(const Alloc& a) : a(a) { }
typedef typename std::allocator_traits<Alloc>::pointer pointer;
void operator()(pointer p) const
{
Alloc aa(a);
std::allocator_traits<Alloc>::destroy(aa, std::addressof(*p));
std::allocator_traits<Alloc>::deallocate(aa, p, 1);
}
private:
Alloc a;
};
template<typename T, typename Alloc, typename... Args>
auto
allocate_unique(const Alloc& alloc, Args&&... args)
{
using AT = std::allocator_traits<Alloc>;
static_assert(std::is_same<typename AT::value_type, std::remove_cv_t<T>>{}(),
"Allocator has the wrong value_type");
Alloc a(alloc);
auto p = AT::allocate(a, 1);
try {
AT::construct(a, std::addressof(*p), std::forward<Args>(args)...);
using D = alloc_deleter<Alloc>;
return std::unique_ptr<T, D>(p, D(a));
}
catch (...)
{
AT::deallocate(a, p, 1);
throw;
}
}
int main()
{
std::allocator<int> a;
auto p = allocate_unique<int>(a, 0);
return *p;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3032 次 |
| 最近记录: |