应该allocator construct()默认初始化而不是值初始化? [英] Should allocator construct() default initialize instead of value initializing?
问题描述
作为此问题的后续工作,默认分配器( std :: allocator< T> ;
)需要实现构造
,如下所示(根据[default.allocator]):
template< class U,class ... Args>
void construct(U * p,Args& ... args);
:: new((void *)p)U(std :: forward& Args(args)...)
<也就是说,总是值初始化。其结果是 std :: vector< POD> v(num)
,对任何pod类型,将值初始化 num
元素 - 这比默认初始化 num
元素。
为什么没有† std :: allocator
提供默认初始化额外的过载?也就是说,像(借用 Casey ):
template< class U>
void construct(U * p)noexcept(std :: is_nothrow_default_constructible< U> :: value)
{
:: new(static_cast< void *>(p)
}
有没有理由更喜欢在呼叫中初始化值?这似乎令我惊讶的是,这打破了通常的C ++规则,我们只为我们想要使用的付出。
† 我认为这样的改变是不可能的, code> std :: vector< int> v(100)会给你100 0
s,但我想知道为什么是这样的情况...很容易需要 std :: vector< int>在
new int [100]
和 new int [100]之间存在差异的相同方式, 100] {}
。
在C ++ 03中,分配器用于执行复制初始化的指针和值:
20.1.6表34
a.construct(p,t)
效果:
:: new((void *)p)T(t)
code> construct 采取两个参数可以追溯到1994年(第18页)。正如你所看到的,在Stepanov概念中,它不是分配器接口的一部分(它不应该是可配置的),并且作为包装器存在于placement new。
只有方法知道肯定会问斯蒂芬诺本人,但我想这是因为如下:如果你想构造一些东西,你想用特定的值初始化它。如果你想要你的整数未初始化,你可以省略构造
调用,因为它不需要POD类型。后来构造
和其他相关的功能被捆绑到分配器和容器中参数化导致最终用户初始化的一些失去控制。
因此,似乎没有默认初始化是因为历史原因:没有人知道它的重要性,当C ++标准化,以后的版本的标准不会引入破裂的变化。 / p>
As a followup to this question, the default allocator (std::allocator<T>
) is required to implement construct
as follows (according to [default.allocator]):
template <class U, class... Args> void construct(U* p, Args&&... args);
Effects:
::new((void *)p) U(std::forward<Args>(args)...)
That is, always value-initialization. The result of this is that std::vector<POD> v(num)
, for any pod type, will value-initialize num
elements - which is more expensive than default-initializing num
elements.
Why didn't† std::allocator
provide a default-initializing additional overload? That is, something like (borrowed from Casey):
template <class U>
void construct(U* p) noexcept(std::is_nothrow_default_constructible<U>::value)
{
::new(static_cast<void*>(p)) U;
}
Was there a reason to prefer value initialization in call cases? It seems surprising to me that this breaks the usual C++ rules where we only pay for what we want to use.
†I assume such a change is impossible going forward, given that currently std::vector<int> v(100)
will give you 100 0
s, but I'm wondering why that is the case... given that one could just as easily have required std::vector<int> v2(100, 0)
in the same way that there are differences between new int[100]
and new int[100]{}
.
In C++03 Allocators construct
member took two arguments: pointer and value which was used to perform copy-initialization:
20.1.6 Table 34
a.construct(p,t)
Effect:
::new((void*)p) T(t)
construct
taking two parameters can be traced back to 1994 (pg. 18). As you can see, in orignal Stepanov concepts it wasn't part of allocator interface (it wasn't supposed to be configurable) and was present just as wrapper over placement new.
Only way to know for sure would to ask Stepanov himself, but I suppose that reason was following: if you want to construct something, you want to initialize it with specific value. And if you want your integers uninitializated, you can just omit construct
call since it is not needed for POD types. Later construct
and other related function were bundled into allocators and containers were parametrized on them introducing some loss of control on initialization for end user.
So it seems that lack of default initialization is for historical reasons: nobody though about its importance when C++ was standardized and later versions of the Standard would not introduce breaking change.
这篇关于应该allocator construct()默认初始化而不是值初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!