std :: vector,默认构造,C ++ 11和打破更改 [英] std::vector, default construction, C++11 and breaking changes
问题描述
考虑下面花园种类的共享身体习语课程:
/ p>
struct S
{
S():p_impl(new impl){}
private :
struct impl;
boost :: shared_ptr< impl> p_impl;
};
当您尝试按以下方式将它们放入向量时会出现乐趣:
std :: vector< S> v(42)。
现在,至少使用MSVC 8, v
共享同一个
impl
成员。实际上,导致这是向量
构造函数的原因:
template<类型名称T,类型名称A = ...>
类向量
{
vector(size_t n,const T& x = T(),const A& a = A
...
};
在这种情况下,只有一个 S
得到默认构造,从向量
的 n
元素被复制。
现在,使用C ++ 11,有一些右值引用。所以它不能这样工作。如果向量
被构造为
std :: vector< S> v(42)。
那么实现会选择默认构造 n
向量中的对象,因为复制构造可能不可用。这将是一个突破性的变化。
我的问题是:
- C ++ 03标准规定
std :: vector
必须具有如上定义的构造函数,即。使用默认参数?特别是有保证向量对象的条目被复制而不是默认构造吗? - C ++ 11标准对同一点说什么?
- 我认为这是C ++ 03和C + 11之间发生突变的可能性。是否已调查此问题?解决了吗?
PS:请不要评论类的默认构造函数 S
上面。
++ 03标准要求
std :: vector
必须具有如上定义的构造函数,即使用默认参数?特别是有保证向量对象的条目被复制而不是默认构造?
是,指定的行为是复制 x
n
次,以便容器初始化为包含 n
元素,这些元素是 x
。
C ++ 11标准点?
在C ++ 11中,此构造函数已变成两个构造函数。
vector(size_type n,const T& x,const Allocator& = Allocator()); //(1)
explicit vector(size_type n); //(2)
除了它不再有第二个参数的默认参数(1)的工作方式与C ++ 03中的相同: x
已复制 n $ <$ p>
代替 x
的默认参数,(2)已添加。此构造函数值 - 初始化容器中的 n
元素。
如果您需要旧的行为,可以通过提供第二个参数来调用(1)构造函数调用:
std :: vector< S> v(42,S());
作为C ++ 03和C ++ 11之间断开更改的可能性。我认为这是一个突破性的改变C ++ 03和C ++ 11之间的可能性。是否已调查此问题?解决了?
是的,如您的例子所示,这确实是一个突变。
由于我不是C ++标准化委员会的成员(我没有特别关注邮件中与图书馆相关的文章),我不会知道在什么程度上讨论了这种突变。
I ran today against a quite subtle issue I'd like to have your opinion on.
Consider the following garden-variety shared-body-idiom class:
struct S
{
S() : p_impl(new impl) {}
private:
struct impl;
boost::shared_ptr<impl> p_impl;
};
The fun appears when you try to put those into vectors in the following way:
std::vector<S> v(42);
Now, with MSVC 8 at least, all the elements in v
share the same impl
member. Actually, what causes this is the vector
constructor:
template <typename T, typename A = ...>
class vector
{
vector(size_t n, const T& x = T(), const A& a = A());
...
};
Under the scenes, only one S
object gets default constructed, the n
elements of the vector
are copied from it.
Now, with C++11, there are rvalue references. So it cannot work like this. If a vector
is constructed as
std::vector<S> v(42);
then most likely, implementations will chose to default construct the n
objects inside the vector, since copy construction may not be available. This would be a breaking change in this case.
My question is:
- Does the C++03 standard mandates that
std::vector
must have a constructor defined as above, ie. with a default argument ? In particular is there a guarantee that the entries of the vector object get copied instead of default constructed ? - What does the C++11 standard say about this same point ?
- I see this as a possibility for a breaking change between C++03 and C+11. Has this issue been investigated ? Solved ?
PS: Please no comments about the default constructor of the class S
above. It was this or implementing some form of lazy construction.
Does the C++03 standard mandate that
std::vector
must have a constructor defined as above, i.e. with a default argument? In particular is there a guarantee that the entries of the vector object get copied instead of default constructed?
Yes, the specified behavior is that x
is copied n
times so that the container is initialized to contain with n
elements that are all copies of x
.
What does the C++11 Standard say about this same point?
In C++11 this constructor has been turned into two constructors.
vector(size_type n, const T& x, const Allocator& = Allocator()); // (1)
explicit vector(size_type n); // (2)
Except for the fact that it no longer has a default argument for the second parameter, (1) works the same way as it does in C++03: x
is copied n
times.
In lieu of the default argument for x
, (2) has been added. This constructor value-initializes n
elements in the container. No copies are made.
If you require the old behavior, you can ensure that (1) is called by providing a second argument to the constructor invocation:
std::vector<S> v(42, S());
I see this as a possibility for a breaking change between C++03 and C++11. I see this as a possibility for a breaking change between C++03 and C++11. Has this issue been investigated? Solved?
Yes, as your example demonstrates, this is indeed a breaking change.
As I am not a member of the C++ standardization committee (and I haven't paid particularly close attention to library-related papers in the mailings), I don't know to what degree this breaking change was discussed.
这篇关于std :: vector,默认构造,C ++ 11和打破更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!