继这个问题之后,我想使用unitialised_allocator
withstd::vector
来避免在构造时默认初始化元素(或resize()
(std::vector
另请参阅此处的用例)。我当前的设计如下所示:
// based on a design by Jared Hoberock
template<typename T, typename base_allocator >
struct uninitialised_allocator : base_allocator::template rebind<T>::other
{
// added by Walter Q: IS THIS THE CORRECT CONDITION?
static_assert(std::is_trivially_default_constructible<T>::value,
"value type must be default constructible");
// added by Walter Q: IS THIS THE CORRECT CONDITION?
static_assert(std::is_trivially_destructible<T>::value,
"value type must be default destructible");
using base_t = typename base_allocator::template rebind<T>::other;
template<typename U>
struct rebind
{
typedef uninitialised_allocator<U, base_allocator> other;
};
typename base_t::pointer allocate(typename base_t::size_type n)
{
return base_t::allocate(n);
}
// catch default construction
void construct(T*)
{
// no-op
}
// forward everything else with at least one argument to the base
template<typename Arg1, typename... Args>
void construct(T* p, Arg1 &&arg1, Args&&... args)default_
{
base_t::construct(p, std::forward<Arg1>(arg1), std::forward<Args>(args)...);
}
};
然后unitialised_vector<>
可以像这样定义模板:
template<typename T, typename base_allocator = std::allocator<T>>
using uninitialised_vector =
std::vector<T,uninitialised_allocator<T,base_allocator>>;
但是,正如我的评论所示,我不能 100% 确定? 中的适当条件是static_assert()
什么?(顺便说一句,可以考虑使用 SFINAE ——欢迎对此提出任何有用的评论)
显然,人们必须避免因试图破坏未初始化对象而引发的灾难。考虑
unitialised_vector< std::vector<int> > x(10); // dangerous.
有人建议(Evgeny Panasyuk 评论)我断言微不足道的可构造性,但这似乎并没有捕捉到上述灾难场景。我只是想检查一下clang所说的std::is_trivially_default_constructible<std::vector<int>>
(或std::is_trivially_destructible<std::vector<int>>
),但我得到的只是clang 3.2的崩溃......
另一个更高级的选择是设计一个分配器,它只省略对象的默认构造,这样做是安全的。