<bdo id='NwGPx'></bdo><ul id='NwGPx'></ul>

<i id='NwGPx'><tr id='NwGPx'><dt id='NwGPx'><q id='NwGPx'><span id='NwGPx'><b id='NwGPx'><form id='NwGPx'><ins id='NwGPx'></ins><ul id='NwGPx'></ul><sub id='NwGPx'></sub></form><legend id='NwGPx'></legend><bdo id='NwGPx'><pre id='NwGPx'><center id='NwGPx'></center></pre></bdo></b><th id='NwGPx'></th></span></q></dt></tr></i><div id='NwGPx'><tfoot id='NwGPx'></tfoot><dl id='NwGPx'><fieldset id='NwGPx'></fieldset></dl></div>

    1. <small id='NwGPx'></small><noframes id='NwGPx'>

      <tfoot id='NwGPx'></tfoot>
      <legend id='NwGPx'><style id='NwGPx'><dir id='NwGPx'><q id='NwGPx'></q></dir></style></legend>

        std::vector、默认构造、C++11 和重大更改

        时间:2023-09-16
          <tbody id='3ax4P'></tbody>

                <bdo id='3ax4P'></bdo><ul id='3ax4P'></ul>
                <i id='3ax4P'><tr id='3ax4P'><dt id='3ax4P'><q id='3ax4P'><span id='3ax4P'><b id='3ax4P'><form id='3ax4P'><ins id='3ax4P'></ins><ul id='3ax4P'></ul><sub id='3ax4P'></sub></form><legend id='3ax4P'></legend><bdo id='3ax4P'><pre id='3ax4P'><center id='3ax4P'></center></pre></bdo></b><th id='3ax4P'></th></span></q></dt></tr></i><div id='3ax4P'><tfoot id='3ax4P'></tfoot><dl id='3ax4P'><fieldset id='3ax4P'></fieldset></dl></div>

                <small id='3ax4P'></small><noframes id='3ax4P'>

              • <legend id='3ax4P'><style id='3ax4P'><dir id='3ax4P'><q id='3ax4P'></q></dir></style></legend>
                  <tfoot id='3ax4P'></tfoot>

                  本文介绍了std::vector、默认构造、C++11 和重大更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  今天我遇到了一个非常微妙的问题,我想征求您的意见.

                  考虑以下花园式的共享体习语类:

                  struct S{S() : p_impl(new impl) {}私人的:结构体;boost::shared_ptr<impl>p_impl;};

                  当您尝试以下列方式将它们放入向量中时,乐趣就会出现:

                  std::vectorv(42);

                  现在,至少在 MSVC 8 中,v 中的所有元素共享相同的 impl 成员.实际上,导致这种情况的原因是 vector 构造函数:

                  template 类向量{向量(size_t n, const T& x = T(), const A& a = A());...};

                  在场景下,只有一个S对象被默认构造,vectorn元素是从它复制过来的.

                  现在,在 C++11 中,有右值引用.所以它不能像这样工作.如果一个 vector 被构造为

                  std::vectorv(42);

                  那么很可能,实现将选择默认构造向量内的 n 对象,因为复制构造可能不可用.在这种情况下,这将是一个重大变化.

                  我的问题是:

                  1. C++03 标准是否要求 std::vector 必须具有如上定义的构造函数,即.使用默认参数?特别是是否可以保证向量对象的条目被复制而不是默认构造?
                  2. C++11 标准对同一点有何看法?
                  3. 我认为这是在 C++03 和 C+11 之间进行重大更改的可能性.这个问题有调查过吗?解决了吗?

                  PS:请不要对上述 S 类的默认构造函数发表评论.就是这样或者实现了某种形式的惰性构造.

                  解决方案

                  C++03 标准是否要求 std::vector 必须具有如上定义的构造函数,即具有默认参数?特别是是否保证向量对象的条目被复制而不是默认构造?

                  是的,指定的行为是 x 被复制 n 次,以便容器被初始化为包含 n 个元素,这些元素都是x 的副本.

                  <小时><块引用>

                  C++11 标准对同一点有何看法?

                  在 C++11 中,这个构造函数已经变成了两个构造函数.

                  vector(size_type n, const T& x, const Allocator& = Allocator());//(1)显式向量(size_type n);//(2)

                  除了第二个参数不再有默认参数外,(1) 的工作方式与在 C++03 中的工作方式相同:x 被复制了 n 次.

                  代替 x 的默认参数,添加了 (2).此构造函数值初始化容器中的 n 元素.没有复制.

                  如果您需要旧的行为,您可以通过为构造函数调用提供第二个参数来确保调用 (1):

                  std::vectorv(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:

                  1. 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 ?
                  2. What does the C++11 standard say about this same point ?
                  3. 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 和重大更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                • <i id='GOTqz'><tr id='GOTqz'><dt id='GOTqz'><q id='GOTqz'><span id='GOTqz'><b id='GOTqz'><form id='GOTqz'><ins id='GOTqz'></ins><ul id='GOTqz'></ul><sub id='GOTqz'></sub></form><legend id='GOTqz'></legend><bdo id='GOTqz'><pre id='GOTqz'><center id='GOTqz'></center></pre></bdo></b><th id='GOTqz'></th></span></q></dt></tr></i><div id='GOTqz'><tfoot id='GOTqz'></tfoot><dl id='GOTqz'><fieldset id='GOTqz'></fieldset></dl></div>

                    <tbody id='GOTqz'></tbody>
                      <bdo id='GOTqz'></bdo><ul id='GOTqz'></ul>
                        1. <tfoot id='GOTqz'></tfoot>
                          1. <small id='GOTqz'></small><noframes id='GOTqz'>

                            <legend id='GOTqz'><style id='GOTqz'><dir id='GOTqz'><q id='GOTqz'></q></dir></style></legend>