无法使用const成员的emplace_back类实例

时间:2014-03-28 17:29:18

标签: c++ c++11 vector default-constructor emplace

我在使用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不会导致编译错误。

1 个答案:

答案 0 :(得分:4)

您的铿锵声版本是什么,clanggcc您的代码就可以了。

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