Вопрос

I have a problem using 'emplace_back' on an instance of a class with const members.

See a sample code listing below.

#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);
}

The compilation error:

% 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.

Seeing this error message:

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

I tried defining an assignment operator (and move and copy constructors, and a destructor) to make sure that the implicitly generated ones do not somehow become private. That did not change anything. I do not see why the assignment operator is "explicitly deleted" in this case case.

Note that changing the class members to be non-const results in no compilation errors.

Это было полезно?

Решение

What is your clang version, your code is fine with clang and gcc.

Of course, it is not possible to default the operator= as it would fail to update the const members, but vector require only MoveConstructible/CopyConstructible and do not use operator= and your code is legal.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top