• <small id='YuxMU'></small><noframes id='YuxMU'>

    <tfoot id='YuxMU'></tfoot>

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

        <legend id='YuxMU'><style id='YuxMU'><dir id='YuxMU'><q id='YuxMU'></q></dir></style></legend>
        • <bdo id='YuxMU'></bdo><ul id='YuxMU'></ul>

        初始化列表构造不可复制(但可移动)对象的向量

        时间:2023-09-15

          <tfoot id='rZNxf'></tfoot>
            <i id='rZNxf'><tr id='rZNxf'><dt id='rZNxf'><q id='rZNxf'><span id='rZNxf'><b id='rZNxf'><form id='rZNxf'><ins id='rZNxf'></ins><ul id='rZNxf'></ul><sub id='rZNxf'></sub></form><legend id='rZNxf'></legend><bdo id='rZNxf'><pre id='rZNxf'><center id='rZNxf'></center></pre></bdo></b><th id='rZNxf'></th></span></q></dt></tr></i><div id='rZNxf'><tfoot id='rZNxf'></tfoot><dl id='rZNxf'><fieldset id='rZNxf'></fieldset></dl></div>
                <tbody id='rZNxf'></tbody>
            1. <legend id='rZNxf'><style id='rZNxf'><dir id='rZNxf'><q id='rZNxf'></q></dir></style></legend>

              <small id='rZNxf'></small><noframes id='rZNxf'>

                  <bdo id='rZNxf'></bdo><ul id='rZNxf'></ul>
                • 本文介绍了初始化列表构造不可复制(但可移动)对象的向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  可以将不可复制但可移动类型的 push_back 右值转化为该类型的向量:

                  One can push_back rvalues of a noncopyable-but-movable type into a vector of that type:

                  #include <vector>
                  
                  struct S
                  {
                      S(int);
                      S(S&&);
                  };
                  
                  int main()
                  {
                      std::vector<S> v;
                      v.push_back(S(1));
                      v.push_back(S(2));
                      v.push_back(S(3));
                  }
                  

                  但是,当我尝试使用相同的右值对向量进行初始化列表构造时,我收到有关需要复制构造函数的错误:

                  However, when I try to initializer-list-construct the vector with the same rvalues, I get errors about a copy constructor being required:

                  #include <vector>
                  
                  struct S
                  {
                      S(int);
                      S(S&&);
                  };
                  
                  int main()
                  {
                      std::vector<S> v = {S(1), S(2), S(3)};
                  }
                  

                  我在使用 GCC 4.7 时遇到以下错误:

                  I get the following errors with GCC 4.7:

                  In file included from include/c++/4.7.0/vector:63:0,
                                   from test.cpp:1:
                  include/c++/4.7.0/bits/stl_construct.h: In instantiation of 'void std::_Construct(_T1*, _Args&& ...) [with _T1 = S, _Args = {const S&}]':
                  include/c++/4.7.0/bits/stl_uninitialized.h:77:3:   required from 'static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const S*, _ForwardIterator = S*, bool _TrivialValueTypes = false]'
                  include/c++/4.7.0/bits/stl_uninitialized.h:119:41:   required from '_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = const S*, _ForwardIterator = S*]'
                  include/c++/4.7.0/bits/stl_uninitialized.h:260:63:   required from '_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = const S*, _ForwardIterator = S*, _Tp = S]'
                  include/c++/4.7.0/bits/stl_vector.h:1185:4:   required from 'void std::vector<_Tp, _Alloc>::_M_range_initialize(_ForwardIterator, _ForwardIterator, std::forward_iterator_tag) [with _ForwardIterator = const S*, _Tp = S, _Alloc = std::allocator<S>]'
                  include/c++/4.7.0/bits/stl_vector.h:362:2:   required from 'std::vector<_Tp, _Alloc>::vector(std::initializer_list<_Tp>, const allocator_type&) [with _Tp = S, _Alloc = std::allocator<S>, std::vector<_Tp, _Alloc>::allocator_type = std::allocator<S>]'
                  test.cpp:11:41:   required from here
                  include/c++/4.7.0/bits/stl_construct.h:77:7: error: no matching function for call to 'S::S(const S&)'
                  include/c++/4.7.0/bits/stl_construct.h:77:7: note: candidates are:
                  test.cpp:6:5: note: S::S(S&&)
                  test.cpp:6:5: note:   no known conversion for argument 1 from 'const S' to 'S&&'
                  test.cpp:5:5: note: S::S(int)
                  test.cpp:5:5: note:   no known conversion for argument 1 from 'const S' to 'int'
                  

                  这应该被允许吗?我认为它没有技术障碍被允许,但我目前手头没有标准......

                  Should this be allowed? I see no technical obstacles to it being allowed, but I don't have the Standard handy at the moment...

                  推荐答案

                  也许 8.5.4.5 的这个条款解释了它(我的重点):

                  Maybe this clause from 8.5.4.5 explains it (my emphasis):

                  一个 std::initializer_list 类型的对象是从一个初始化列表就好像实现分配了一个 N 的数组E 类型的元素,其中 N 是初始化列表.该数组的每个元素都被复制初始化与初始化列表的相应元素,以及构造 std::initializer_list 对象以引用该数组.

                  An object of type std::initializer_list is constructed from an initializer list as if the implementation allocated an array of N elements of type E, where N is the number of elements in the initializer list. Each element of that array is copy-initialized with the corresponding element of the initializer list, and the std::initializer_list object is constructed to refer to that array.

                  所以如果对象是可复制的,你只能从列表初始化.

                  So you can only initialize from lists if the objects are copyable.

                  更新:正如 Johannes 所指出的,复制初始化可以通过复制和移动构造函数来实现,因此仅凭这一点还不足以回答这个问题.然而,这里是 18.9 中描述的 initializer_list 类规范的摘录:

                  Update: As Johannes points out, copy-initialization can be realized by both copy and move constructors, so that alone isn't enough to answer the question. Here is, however, an excerpt of the specification of the initializer_list class as described in 18.9:

                    template<class _E>
                      class initializer_list
                      {
                      public:
                        typedef _E            value_type;
                        typedef const _E&     reference;
                        typedef const _E&     const_reference;
                        typedef size_t        size_type;
                        typedef const _E*     iterator;
                        typedef const _E*     const_iterator;
                  

                  注意没有非常量的 typedef!

                  Note how there are no non-constant typedefs!

                  我只是尝试制作一个 IL 构造函数,它会通过 std::make_move_iterator 遍历初始化列表,但失败了,因为 const T & 无法转换为 T&&.

                  I just tried making an IL constructor which would traverse the initializer list via std::make_move_iterator, which failed because const T & cannot be converted to T&&.

                  所以答案是:你不能离开 IL,因为标准是这样说的.

                  So the answer is: You cannot move from the IL, because the standard says so.

                  这篇关于初始化列表构造不可复制(但可移动)对象的向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:C++:模板类的向量 下一篇:复制后的 std::vector 容量

                  相关文章

                  最新文章

                • <legend id='td5VY'><style id='td5VY'><dir id='td5VY'><q id='td5VY'></q></dir></style></legend>

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

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

                    1. <tfoot id='td5VY'></tfoot>
                        <bdo id='td5VY'></bdo><ul id='td5VY'></ul>