无法用const成员替换类的e_back实例

Unable to emplace_back instance of a class with const members

本文关键字:back 实例 替换 const 成员      更新时间:2023-10-16

在const成员类的实例上使用'emplace_back'有问题。

请参阅下面的示例代码清单。

#include <vector>
using std::vector;
class Data {
  public:
    Data(int a, int b, int c) : a(a), b(b), c(c) {}
    // Removing any/all of these constructors changes nothing!
    Data& operator=(const Data& s) = default;
    Data(const Data& s) = default;
    Data(Data&& s) = default;
    ~Data() = default;
    const int a;
    const int b;
    const int c;
};

int main() {
  vector<Data> v;
  Data e(1,2,3);
  // Problem line
  v.emplace_back(4,5,6);
}
编译错误:
% clang++ a.cc  -std=c++11
In file included from a.cc:1:
In file included from /usr/include/c++/4.6/vector:69:
/usr/include/c++/4.6/bits/vector.tcc:319:16: error: overload resolution selected
      deleted operator '='
          *__position = _Tp(std::forward<_Args>(__args)...);
          ~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/4.6/bits/vector.tcc:102:4: note: in instantiation of function
      template specialization 'std::vector<Data, std::allocator<Data>
      >::_M_insert_aux<int, int, int>' requested here
          _M_insert_aux(end(), std::forward<_Args>(__args)...);
          ^
a.cc:25:5: note: in instantiation of function template specialization
      'std::vector<Data, std::allocator<Data> >::emplace_back<int, int, int>'
      requested here
  v.emplace_back(4,5,6);
    ^
a.cc:9:11: note: candidate function has been explicitly deleted
    Data& operator=(const Data& s) = default;
          ^
In file included from a.cc:1:
In file included from /usr/include/c++/4.6/vector:60:
/usr/include/c++/4.6/bits/stl_algobase.h:546:18: error: overload resolution
      selected deleted operator '='
            *--__result = std::move(*--__last);
            ~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/4.6/bits/stl_algobase.h:578:14: note: in instantiation of
      function template specialization 'std::__copy_move_backward<true, false,
      std::random_access_iterator_tag>::__copy_move_b<Data *, Data *>' requested
      here
      return std::__copy_move_backward<_IsMove, __simple,
             ^
/usr/include/c++/4.6/bits/stl_algobase.h:588:19: note: in instantiation of
      function template specialization 'std::__copy_move_backward_a<true, Data
      *, Data *>' requested here
      return _BI2(std::__copy_move_backward_a<_IsMove>
                  ^
/usr/include/c++/4.6/bits/stl_algobase.h:659:14: note: in instantiation of
      function template specialization 'std::__copy_move_backward_a2<true, Data
      *, Data *>' requested here
      return std::__copy_move_backward_a2<true>(std::__miter_base(__first),
             ^
/usr/include/c++/4.6/bits/vector.tcc:313:4: note: in instantiation of function
      template specialization 'std::move_backward<Data *, Data *>' requested
      here
          _GLIBCXX_MOVE_BACKWARD3(__position.base(),
          ^
/usr/include/c++/4.6/bits/stl_algobase.h:664:48: note: expanded from:
#define _GLIBCXX_MOVE_BACKWARD3(_Tp, _Up, _Vp) std::move_backward(_Tp, _Up, _Vp)
                                               ^
/usr/include/c++/4.6/bits/vector.tcc:102:4: note: in instantiation of function
      template specialization 'std::vector<Data, std::allocator<Data>
      >::_M_insert_aux<int, int, int>' requested here
          _M_insert_aux(end(), std::forward<_Args>(__args)...);
          ^
a.cc:25:5: note: in instantiation of function template specialization
      'std::vector<Data, std::allocator<Data> >::emplace_back<int, int, int>'
      requested here
  v.emplace_back(4,5,6);
    ^
a.cc:9:11: note: candidate function has been explicitly deleted
    Data& operator=(const Data& s) = default;
          ^
2 errors generated.

看到这个错误信息:

a.cc:9:11: note: candidate function has been explicitly deleted
        Data& operator=(const Data& s) = default;

我尝试定义一个赋值操作符(以及移动和复制构造函数,以及析构函数),以确保隐式生成的操作符不会以某种方式变为私有。这并没有改变什么。我不明白为什么在这种情况下,赋值操作符被"显式删除"。

请注意,将类成员更改为非const不会导致编译错误。

你的clang版本是什么,你的代码可以用clang和gcc。

当然,不可能默认operator=,因为它将无法更新const成员,但vector只需要MoveConstructible/CopyConstructible,不使用operator=,您的代码是合法的