2016-09-17 6 views
0

클래스 테스트 일정한 데이터 멤버와C++ 11 CONST 데이터 멤버는 표준 : 삽입은

#include <algorithm> 
#include <iterator> 
#include <vector> 

template <typename T> 
struct MinMax { T min, max; }; 

template <typename T> 
using TList = std::vector<T>; 

template <typename T> 
class Test 
{ 
    private: 
     const T a, b;   
     const MinMax <T> m; 
    public: 
     Test() : a(0), m{ 0, 0 }, b(0.0) {}; 
    public: 
     T getA() const { return a; } 
     MinMax <T> & getMinMax() const { return m; } 
     T getB() const { return b; } 
     Test(const Test &t) : a(t.a), b(t.b), m(t.m) {} 
}; 

간단한 예 복사있다. 생성자 대신에 데이터는 변경되지 않습니다. std :: inserter를 사용하여 다른 벡터에 Test 개체의 벡터를 복사하고 싶습니다. 나는 복사 생성자가 충분하지 않은 것을 놀란다

int main() 
{ 
    TList <Test <double> > t1; 
    TList <Test <double> > t2; 
    Test<double> t; 
    t1.push_back(t); 
    std::copy(t2.begin(), t2.end(), std::inserter(t1, t1.begin())); 

    return 0; 
} 

다음과 같은 컴파일러 오류 (VS2015)가 나타납니다 :

Error C2280 'Test<double> &Test<double>::operator =(const Test<double> &)': attempting to reference a deleted function Const 

이 데이터 구성원을 const 수 있도록하고 다른에 복사를 수행하는 것이 가능 방법 (일부 해킹 :-))? 또는 연산자 = 정의되어야하므로 데이터 멤버는 const가 될 수 없습니다 (const 데이터 멤버가있는 객체에 할당 할 수 있습니까?)?

도움 주셔서 감사합니다.

+0

확실하지 않은 경우'std :: move()'를 (를) 사용해보십시오. –

+1

const 데이터 멤버를 사용하면 복사 할당이나 이동 할당을 사용할 수 없습니다 (무서운 const 캐스트 해킹없이) –

+0

@ 리차드 호지스 : 나는 그것이 불가능하다고 두려워했습니다. 감사. – justik

답변

3

vector에 대한 삽입은 삽입 된 요소 뒤에 모든 요소를 ​​다시 할당하고 해제 된 슬롯에 삽입 된 요소를 할당합니다. 즉

, 당신은하지 표준이 Asssignable이 (a = b가 정의한)로 표준 컨테이너의 요소를 필요로하기 때문에 전체 기능을 제공 할 수 있습니다. 외에 당신은 또한 다시 밀어하여 vector에 const를 회원들과 요소를 추가 할 수 있습니다 operator= 자신을 작성하는 확실한 해결책에서

:

std::copy(t2.begin(), t2.end(), std::back_inserter(t1)); 

을하지만, 그런 종류의 표준에 대한 작업입니다; push_back은 양도 할 필요가 없지만 다른 기능이 필요할 수 있습니다.

또는 당신이 vector의 연속 메모리 캐시 지역의 모든 혜택을 거래 삽입 양도성 필요로하지 않는 용기, 예컨대 :

template <typename T> 
using TList = std::list<T>; 

를 사용할 수 있습니다.

결산 메모에서 본인의 구조에서 데이터 멤버를 선언하지 않도록하는 경향이 있습니다. const 내부적 인 지정 가능성이 필요한 일반 컨테이너의 문제 때문입니다. 귀하의 예에서 개인 회원들로부터 const을 제거하면 읽기 전용 필드 (외부의 getter를 통해서만 액세스 할 수 있음)를 남길 수 있습니다.

+0

@ Tomek : 아주 좋은 대답, 자세한 설명 주셔서 감사합니다. – justik