2014-10-24 2 views
1

복사 생성자가 아닌 사용자 정의 할당자를 사용하여 std :: vector의 크기를 조정할 수 있습니까?사용자 정의 할당자를 사용하여 크기 조정

#include <vector> 
#include <iostream> 

class A{ 
public: 
    A(int x){ 
    std::cout<<" new a:"<<this<<" "<< x<<std::endl; 
    } 
}; 

template<typename T> 
class ParamAlloc:public std::allocator<T>{ 
public: 
    template<typename U> struct rebind {typedef ParamAlloc other;}; 

    void construct(typename std::allocator<T>::pointer p, typename std::allocator<T>::const_reference val){ 
    new ((void*)p) T(47); 
    } 


    void destroy(typename std::allocator<T>::pointer p){ 
    ((T*)p)->~T(); 
    } 
}; 


int main(){ 

    ParamAlloc<A> all; 
    std::vector<A,ParamAlloc<A> > ac(all); 
    ac.resize(5); 
} 

하지만 여전히 나는 (A ::를 인스턴스화하려고 인해 컴파일로 컴파일 에러)를 얻을 : 여기

내가 뭘하려합니다.

이 질문과 관련하여 A 클래스의 개체 벡터를 할당하는 가장 좋은 방법은 무엇입니까 (C++ 11 이전 버전). A 개체의 매개 변수는 매개 변수를 사용하지만 A 개체는 복사되지 않아야합니다.

답변

2

사전 C++ 11 resize 멤버는 다음과 같이 정의된다 :

resize(size_type n, const T& = T()); 

그래서 당신은 실제로 분명 기본 생성자가 필요 ac.resize(5, A())을 의미 ac.resize(5)로 호출 할 때. C++ 03의 유일한 해결 방법은 벡터의 크기를 조정하고 A(99)의 복사본으로 새 요소를 구성하는 복사 대상 객체 인 ac.resize(5, A(99))을 제공하는 것입니다. 복사본은 사용자 지정 할당 자에 의해 수행되며 실제로 복사 생성자를 사용하는 대신 A(47)으로 생성합니다. resize()에 대한

요구 사항은 C++ (11)에 대한 완화와 C++ 11 표준은 vector::resize()

가 요구하는 [vector.capacity] 말한다되었습니다T*thisMoveInsertableDefaultInsertable을한다 . 통화가 할당 m이 유효한 경우에 m.construct(p)를 호출하려고합니다

allocator_traits<A>::construct(m, p) 

,하지만 당신의 할당이 지원하지 않기 때문에 그것을 할 것이다 :

DefaultInsertable

이 유효해야합니다

::new((void *)p) T() 

기본 생성자가 필요합니다.

사용자 정의 할당자가 resize에 사용되도록하려면 construct 멤버를 제공해야합니다.이 멤버는 하나의 인수만으로 호출 할 수 있습니다.

void construct(typename std::allocator<T>::pointer p){ 
    new ((void*)p) T(47); 
} 

즉, 크기 조정시 기본 생성자가 필요하지 않습니다.

0

A(int x)에 대한 기본 매개 변수를 제공하면 컴플리이가 전달됩니다.

class A{ 
public: 
    A(int x=0){//here !! 
    std::cout<<" new a:"<<this<<" "<< x<<std::endl; 
    } 
}; 

는 그리고 그 결과는 다음과 같습니다

new a:0x7fffe01aab5f 0 
new a:0x1c7d010 47 
new a:0x1c7d011 47 
new a:0x1c7d012 47 
new a:0x1c7d013 47 
new a:0x1c7d014 47 
+1

이 장난감의 예에서는 이렇게 할 수 있습니다. 다른 경우에는 (매개 변수가 실제로 생성 시간에 필요합니다) 아니오. –

0

C++ 표준은 주어진 컨테이너에 대한 항목 유형에 대한 특정 요구 사항을 정의한다. 예를 들어 pre-C++에서 벡터에 저장할 수 있습니다. 11 T must meet the requirements of CopyAssignable and CopyConstructible. 크기 조정을 사용하려면 T must meet the requirements of DefaultConstructible을 사용하십시오. 그래서, 여러분이 성취하려고 시도하는 것은 pre-C++ 11 표준에 의해 명시 적으로 금지되어 있습니다. 어쩌면 vector::resize 대신 vector::reserve을 사용하거나 다른 컨테이너 만 있으면됩니다. C++ 11에서도 가능합니다. Jonathan Wakely의 답변을 참조하십시오.

+0

@Jonathan Wakely, 당신 말이 맞아요. 나는 어떻게 든 그가 C++ 11 이전 동작에 관심이 있다고 생각했습니다. 혼란을 피하기 위해 내 대답을 수정했습니다. – dewaffled

관련 문제