2012-03-15 1 views
3

나는 일이 어떻게 작동 하는지를 알고 싶어하며 C++ 표준 라이브러리를 깊이 파고 들었다. 다른 날에 나에게 뭔가가 생겼다.은 uninitialized_copy/fill입니다 (처음에는 마지막으로 dest의 경우 A & a). C++ 표준의 감독은 무엇입니까?

containters (예 : std::vector<int, std::allocator<int> >)는 할당에 지정된 할당자를 사용해야합니다. 특히 표준 말한다 :이 절 복사 각각의 첫번째 매개 변수에서 할당 인수에 정의 된 모든 컨테이너 유형에 대한

23.1.8

복사 생성자. 모든 이러한 컨테이너 유형의 다른 생성자는 컨테이너 값 유형과 동일한 값 유형을 갖는 할당자인 Allocator & 인수 (20.1.5)를 사용합니다. 이 인수의 복사본은 각 컨테이너 객체의 수명 동안 모든 생성자가 할당을 수행하고 모든 구성원이 함수를 사용하는 데 사용됩니다. 이 절에 정의 된 모든 컨테이너 유형에서 컨테이너에서 get_allocator() 은 컨테이너를 생성하는 데 사용 된 Allocator 객체의 복사본을 반환합니다. 이 같은

또한 나중에 말한다 표준에서 (몇 가지 다른 장소에서하지만 난 하나를 선택할 수 있습니다) 일 :

explicit deque(size_type n, const T& value = T(), const Allocator& = Allocator()); 

효과

는 : 값의 n 개의 사본이있는 양단 큐를 구축 지정된 할당자를 사용합니다.

제 질문에 대한 답변입니다.

vector<T, A>::vector(const vector& x) 

이 같은 것을 볼 수 있습니다 :

의는 예를 들어, 같은 것을 구현할 수있는 자연스럽고 효율적인 방법으로 std::vector 보자 특히

template <class T, class A> 
vector<T, A>::vector(const vector& x) { 
    pointer p = alloc_.allocate(x.size()); 
    std::uninitialized_copy(x.begin(), x.end(), p); 
    first_ = p; 
    last_ = p + x.size(); 
    end_ = p + x.size(); 
} 

을, 우리는 몇 가지 메모리를 할당하고 모든 회원을 복사하여 복사하십시오. new value_type[x.size()]과 같은 작업을 수행하지 않아도되므로 기본으로 배열을 덮어 씁니다.

하지만,이 복사 건설을 수행 할 할당을 사용하지 않는 ... 내가 수동으로이 같은 수행하는 루프를 작성할 수

:

while(first != last) { 
    alloc_.construct(&*dest++, *first++); 
} 

을하지만 그건 낭비 , std::uninitialized_copy과 거의 동일하지만 유일한 차이점은 배치 new 대신 할당자를 사용한다는 것입니다.그래서

, 당신은 표준이 (나에게 겉으로는 명백한)을이없는 감독이 같은 함수의 집합이라고 생각 :

template <class In, class For, class A> 
For uninitialized_copy(In first, In last, For dest, A &a); 

template <class In, class Size, class For, class A> 
For uninitialized_copy_n(In first, Size count, For dest, A &a); 

template <class For, class T, class A> 
void uninitialized_fill(For first, For last, const T& x, A &a); 

template <class For, class Size, class T, class A> 
void uninitialized_fill_n(For first, Size count, const T& x, A &a); 

내가 상상 그 기능의 이러한 유형 (수동으로 구현하는 것이 쉽지 않을지라도 ... 예외를 안전하게 만들려고 할 때까지) 컨테이너와 컨테이너를 구현하고 할당자를 사용하면서 복사 생성물을 효율적으로 사용하려는 경우 상당히 유용 할 것입니다.

생각하십니까?

+0

무엇을 묻는 중입니까? 왜'uninitialized_' {'copy','copy_n','fill','fill_n'}가 할당자를 취하지 않는 겁니까? –

+0

적어도 할당자를 사용하는 과부하가없는 이유를 묻습니다. 이는 할당자를 사용하여 데이터 구조를 효율적으로 구성하는 데 유용 할 것입니다. –

+0

그래서 "예"입니다. –

답변

2

나는 그것을 "감독"이라고 부를 수 있을지 확신하지 못합니다.

아니요, 사용자는 이러한 특수 알고리즘에 자신의 할당자를 제공 할 수 없습니다. 그러나 표준에 포함되지 않은 다른 것들도 있습니다.

@ MarkB는 표준 (이 범위는 컨테이너의 할당 자에 대해 알지 못함)을 수행하지 않아야한다는 매우 좋은 이유를 확인합니다. 나는 그것이 단지 내재적 인 한계라고 말할만큼 멀리 갈 것입니다.

할당자가 무엇을해야하는지 알면서 언제든지 uninitialized_copy을 다시 발명 할 수 있습니다. 두 줄의 for 루프 일뿐입니다.

+0

충분히 간단하게 시도하십시오. 'try' /'catch'에서 모든 것을하고 싶었고'catch'에서 지금까지 성공한 객체를 모두 없애려고하기 때문에 스레드 안전성을 원한다면 약간 더 복잡해집니다. –

+0

@Evan : True.표준에있는 "effects"스 니펫에는 '다음과 같은 알고리즘에서 예외가 발생해도 효과가 없다는 것을 알려주지 만, 처리를 포함하지 않습니다.' –

+0

예외가 발생 했습니까? –

1

이러한 함수가 자유 함수라면 할당 자 유형이 반복자에 의해 유지되지 않으므로 컴파일러가 할당 자 불일치를 감지 할 수있는 방법이 없습니다. 이것은 차례 차례로 발견하기 어려운 다양한 문제를 야기 할 수 있습니다.

+0

내 선택의 할당자를 사용하여 직접 동일한 초기화 루프를 직접 작성하는 것보다 더 힘들지 않습니까? 나는 그것이 거의 같다고 생각한다. –

+0

+1 분명히 정답입니다. – Mehrdad