2012-06-11 4 views
3

할당에 서로 다른 소스에서 변환 생성자/할당을 제공하지 않습니다, 왜 template< typename Elem, typename Traits, typename Alloc > basic_string { ... }은 제공하지 않습니다 모두 존중하는 그것은 아주 사소한 것 같다 왜 표준 유형은 예를 들어

template< typename OtherAlloc > 
basic_string(const basic_string< Elem, Traits, OtherAlloc >& a_Other) { ... } 

같은 변환 생성자를 구현 할당 자. 현재의 상황은 할당 자의 종류가 다른 유형 사이의 인터페이스가 매우 성가시다.

+1

할당 자만 다른 표준 템플릿 유형간에 변환하는 템플릿 함수를 구현하는 것은 그리 어렵지 않을 것입니다. (나는이 질문이 유효하지 않다는 것을 말하지 않고있다 - 확실히 - 단지 이것의 주위에 일하기 위하여 요구 된 양은 많지 않아야한다.) – cdhowie

+0

그래, 변환은 자유로운 연산자가 될 수 없다. 그러나 내 코드베이스에서 명시 적으로 변환해야하지만, 여전히 유일한 해결책이 될 수 있습니다. ( – Ylisar

+0

예, 자동 변환은 유감스럽게도 불가능합니다. – cdhowie

답변

3

Standard 해시는 할당 자 재미를 허용하지 않으며 std::stringstd::wstring을 해시 할 수 있지만 std::basic_string<char, std::char_traits<char>, custom_alloc>은 해시 할 수 없습니다. 또한 할당자를 사용하여 unordered_map 또는 unordered_set을 만들 수 없습니다. 액세스 할 수없는 구현 정의 상수가 기본값 인 버킷 번호도 제공해야하므로 실제로 무엇인가를 만들어야합니다. 지원은 일반적으로별로 좋지 않습니다.

비교적 간단하게 아무도 그러한 기능을 제안하지 않았거나이 사용 공간을 탐색하지 못했습니다.

+0

믿을 수 없습니다. 'tuple'과'pair '로 작업 할 때 일어나는 이유는 이것 때문입니다 : ( –

+0

@MooingDuck :'tuple'과'pair'는 할당 자와 무엇을해야합니까? 아무도 그것들을 제안하지 않았기 때문에 표준이 일어난다. 왜 이것이 다른 것일까 요? –

+0

@NicolBolas : 서로 다른 타입의 타입을 포함하고있는'튜플/쌍 '으로부터'tuple'과'pair'를 만들 수 있습니다. 그리고 그것은 OP가 요구하는 방식으로 _ 거의 정확하게 동작합니다. 'tuple' /'pair'가 거의 그것을 수행한다면, 왜 "진짜"컨테이너가 아닌가? (C++ 11 Jan2012 §20.4.2.1/26) –

1

문제는 보이는 것보다 훨씬 어렵습니다. 할당 자 유형은 객체 유형의 일부이기 때문에 할당 자만 다른 유형 간에는 거의 상호 작용이 허용되지 않습니다. 첫 번째 예는 상수 참조로 std::string을 사용하는 함수는 다른 할당자를 사용하는 문자열을 사용할 수 없다는 것입니다. 하나의 특별한 경우는 사물의 건설 중이다. 실제로 여기에서는 더 어려운 경우 일 수 있습니다. allocator2 스택에 로컬 경기장을 사용,

// Assume that you could construct from a different allocator 
std::vector<int, allocator1> f() { 
    std::vector<int, allocator2> r; 
    // fill in 
    return r; 
} 
int main() { 
    std::vector<int, allocator3> x = f(); 
} 

allocator1std::allocator<int> (즉, 기본 할당) 인 것을 고려하고 allocator3 공유 메모리를 사용할 수 있습니다 :

예를 들어 다음과 같은 코드를 생각해 보자. 이론의 코드는, 벡터 r은 매우 간단 생성되고 r에서 return 문 복사하여 만든 새 임시에 데이터로 채워, 그리고 마지막으로 x 그 일시적인에서 복사에 의해 구성된다. 문제는 표준에서 가능한 한 많이 복사하는 것을 피할 수 있다는 것입니다. 위의 특정 예제 (및 할당 자 무시)에서는 컴파일러가 두 복사본을 모두 비우고 버퍼를 한 번만 만들었습니다. 이는 빠르고 효율적입니다. 그러나 할당자가 잠재적으로 달라지면 NRVO 및 다른 유형의 복사 방지가 비활성화되어야합니다. 이러한 최적화가 활성화 된 경우 을 사용하는 로컬의은 이미 파괴 된 로컬 영역을 사용하므로 정의되지 않은 동작이 발생합니다.

하나의 할당자를 가진 컨테이너에서 다른 구성 자로 복사 구성을 가능하게함으로써, 엉망이되거나, 현재 표준에있는 것보다 더 깊은 혼란을 겪을 수 있습니다. 여기서 상태 저장 할당 자와 관련된 모든 종류의 흥미로운 문제가 발생할 수 있습니다 (스레드 간 할당자를 사용하고 데이터를 데이터를 공유 대기열로 이동한다고 가정하면 다른 스레드에서 스레드 별 할당자가 작성한 객체를 보유한 하나의 스레드로 끝날 수 있으며, 스레드 할당자가 잠금에 대한 경합을 피하면 명백하게 안전한 코드에 경쟁 조건을 생성 할 수 있습니다 ....


이것은 오래된 p입니다. C++위원회 Towards a better allocation model에 C++ 03 할당 모델에 대한 우려를 제기하고 다형성 할당 자 유형 (자체의 문제가 있음)을 제안합니다.그것은 흥미로운 읽기를 만들지 만, 세부 사항에주의를 기울여야합니다. 모든 것이 좋은 것처럼 보이지는 않습니다. 두 가지 옵션 (또는 C++ 11과 유사한 C++ 11 버전)을 사용하는 데는 몇 가지 함정이 있습니다. 버전)

+1

Yupp, 할당자가 다른 경우에는 NRVO가 없습니다. 나는 할당 자들이 일치하지 않을 때 어떤 종류의 데이터 이동이 엄격히 금지된다는 것을 이해하지만, 최고의 전문화 규칙 때문에 할당 자들이 일치 할 때 최선의 경우를 이용하는 것이 상당히 쉬울 것 같다. – Ylisar

+0

@Ylisar : 문제는 컴파일러가 할당자가 두 번째 복사본에서 일치하는지 여부를 알 수 없다는 것입니다. 즉, 호출자는 컨텍스트의 객체 공간을 할당 한 다음 함수를 호출합니다. 이 함수는'r'에서 return 문으로 복사를 생략 할 수 있지만 호출자의 컨텍스트에서 할당자가 동일하거나 호환되는지 여부를 알 수 없습니다. 또한 보이는 것보다 추적하기가 더 힘듭니다. 할당자를 재사용 할 수 있는지 여부를 어떻게 알 수 있습니까? –

+0

@MooingDuck : 마지막 단락까지는 다른 할당 자 유형의 복사본 구성이 허용되었다고 전제로 가정 한 것입니다. 즉, Q.가 묻는 질문이 허용되면 위의 문제가 발생합니다. 즉, 할당자가있는 모든 유형의 모든 사본 추출을 비활성화하거나 면도기 가장자리를 밟고있는 것입니다. –