2014-03-28 2 views
2

const 멤버가있는 클래스의 인스턴스에서 'emplace_back'을 사용하는 데 문제가 있습니다.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); 
} 

컴파일 오류 : 확인

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

내가 할당 연산자를 정의하는 시도 (그리고 생성자를 이동하고 복사하고 소멸자) :

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

이 오류 메시지가 표시 암시 적으로 생성 된 것들은 어쨌든 사적이되지 않는다. 그것은 아무것도 바뀌지 않았습니다. 이 경우 대입 연산자가 "명시 적으로 삭제"된 이유는 알 수 없습니다.

클래스 멤버를 비 const로 변경하면 컴파일 오류가 발생하지 않습니다.

+1

참고 : const (또는 관련하여 참조) 멤버는 변경할 수 없으므로 컴파일러에서 생성 한 것들을 포함하여 복사/이동 할당이나 이동 생성자를 작성하는 것은 어렵지 않습니다. – Nevin

+0

네, 맞습니다. 그러나 복사 생성자가 const 멤버가있는 클래스에 허용되지 않는 이유를 모르겠습니다. 중간에있는 오류 메시지를보십시오'a.cc:9:11 : 참고 : 후보 함수가 명시 적으로 삭제되었습니다. 데이터 및 연산자 = (const Data & s) = 기본값; – WaelJ

답변

4

당신의 코드 버전은 clanggcc입니다. 물론

, 그것이 CONST 멤버를 업데이트 실패로 operator= 기본 할 수 없습니다 만, 벡터는 MoveConstructible/CopyConstructible을 필요로하고 operator=를 사용하지 않고 코드는 합법적이다.

+0

우분투 버전 3.0-6ubuntu3이 있음 – WaelJ

+0

@ 0x499602D2 예 업데이트가 아니라. – galop1n

+0

동의합니다. [코드가 잘 작동합니다] (http://ideone.com/wxriyG). –