從之後,我想用一個unitialised_allocator
用,比如說,std::vector
避免在建築元素(或std::vector
(的resize()
的默認初始化也看到here的使用情況)我現在的設計是這樣的:。如何使我的uninitialised_allocator安全?
// 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.
有人建議(由葉夫根Panasyuk評論),我斷言瑣碎的構造性,但是這似乎並沒有趕上以上的災難場景。我只是試圖檢查什麼鏗鏘說關於std::is_trivially_default_constructible<std::vector<int>>
(或std::is_trivially_destructible<std::vector<int>>
),但我得到的是崩潰的叮噹3.2 ...
另一個更先進的選項將設計一個分配器,它只能使用默認構造爲此可以安全的物體。
你可能也想的Elid完全'任何電話destruct',只要類型是微不足道的。 – Xeo
@Xeo好點!將以類似的方式添加。實際上,爲什麼標準不支持這種類型的微不足道的優化? – Walter
@Xeo雖然我會想到,在大多數危急情況下,瑣碎類型的破壞會被優化掉。 – Walter