2014-07-13 3 views
0

현재 내 자신의 벡터 클래스로 실험하는 동안 오류가 발생했습니다. 좀 더 구체적으로 말하자면 메모리 할당 목적으로 std :: allocator 클래스를 사용하는 템플릿 기반 클래스입니다. 더 구체적으로, 오류는 내 범위 생성자 함수에서 2 입력 반복자를 사용하고 "uninitialized_copy"함수를 복사 용도로 사용합니다. 여기초기화되지 않은 복사 오류

#include <memory> 
#include <iostream> 

template <typename T, typename allocator_type = std::allocator<T>> 
class vector 
{ 
public: 

// fill ctor 2 
vector (size_t n, const T& val, 
     const allocator_type& alloc = allocator_type()) 
    : my_alloc(alloc), 
    begin_(my_alloc.allocate(n)), 
    end_(begin_ + n), 
    size_(n), 
    capacity_(n) 
{ 
    std::uninitialized_fill(begin(), end(), val); 
} 

// range ctor 
template <typename InputIterator> 
vector (InputIterator first, InputIterator last, 
     const allocator_type& alloc = allocator_type()) 
    : my_alloc(alloc), 
    size_(0), 
    begin_(0), 
    end_(0), 
    capacity_(0) 
{ 
    // Poor method for finding input container size, a better solution perhaps? 
    InputIterator f = first; 
    while (f++ != last) 
    ++size_; 

    begin_ = my_alloc.allocate(size()); 
    end_ = begin_ + size(); 
    capacity_ = size(); 

    std::uninitialized_copy(first, last, begin_); 
} 

    T* begin() { return begin_; } 
    T* end() { return end_; } 
    size_t size() { return size_; } 
    size_t capacity() { return capacity_; } 

private: 
    allocator_type my_alloc; 
    size_t size_, capacity_; 
    T* begin_, *end_; 
}; 

int main() 
{ 
    vector<int> lst(10, 5); 
    vector<int> lst2(lst.begin(), lst.end()); 
} 

지금 내가 컴파일 코드의 그루터기는, 내가 그것을 구조체 표준에서 어떤 유형의 이름 VALUE_TYPE :: iterator_traits, 생성자 등의 내 다른 유형과 같은 이상한 "에 대해 뭔가를 말한다 오류가 발생 덧붙여 필자는 컴파일러가 "int *"대신 "int"가되도록 "InputTterator"유형을 추론했음을 알았습니다.

나는 내 머리카락을 꺼내 ​​왔습니다. 지난 몇 시간 동안 디버깅을 시도했지만 아무런 해결책도 찾을 수없는 것 같습니다. 어떤 도움이라도 대단히 감사하겠습니다.

감사합니다.

편집 : 죄송합니다. 실수로 내 부분에. 템플릿 매개 변수의 일부로 2 int를 보내는 것은 의도적 인 것이 아닙니다. 위의 코드를 편집했습니다. 이제는 적절한 fill ctor와 범위 ctor가 있습니다. main 함수는 이제이 ctors를 기반으로 2 개의 벡터를 만듭니다. 오류는 여전히 남아 있습니다. 다시, 내 부분에 큰 실수!

+0

'(10,5)'가 * 반복기 * 쌍을 구성하는 방법을 설명하십시오. 범위 생성자 외에도 생성자가 없으며 두 개의 매개 변수와 기본 값 할당자가 필요합니다. 두 개의 int 값은 단독 생성자와 선언문을 일치 시키지만 사용하지는 않습니다. 그래서 ... 그러지 마? – WhozCraig

답변

1

"Int *"대신 "InputTterator"유형이 "InputTterator"유형으로 추론되었음을 알았습니다. uninitialized_copy 내에서 사용되는 전문 iterator_traits<int> 실제로 value_type 구성원이 없기 때문에

vector<int> lst(10, 5); // what else can it deduce than int? 

당신이 얻을 오류 :

음이 한 물론, 당신은 int 생성자에 인수를이야 통과시켰다.

당신이 (단독으로 크기를 얻기 위해 범위의 입력을 통해 가지 않기 위해)이 (partialy 의사) 같은 것입니다 대신 어떻게해야하나요 :

InputIterator f = first; 
    size_t current_size = 0; 
    while (f != last) { 
     if (current_size < size_) { 
      new (begin+current_size) T(*f); 
      ++current_size; 
     } else { 
      // allocate new buffer and copy any 
      // existing elements over 
      // (think about exception safety here) 
     } 
     ++f; 
    } 

이것은 당신이 입력 반복자와 함께 할 수있는 최선이다. 또 다른 옵션은 iterator 범주가 InputIterator인지 확인하여 산술을 허용 할 때 크기를 미리 계산하는 구현에 태그를 지정할 수 있도록하는 것입니다.

EDIT (응답은 영업 이익의 편집) :

그래서 문제가 당신이 그것을 원하지 않을 경우 두 반복자와 생성자 템플릿이 호출 될 것입니다. C++ 11 이전의 표준 라이브러리의 벡터 클래스에도 동일한 문제가있었습니다. 표준은 추론 된 유형이 반복자가 아닌 경우 해당 생성자가 과부하 해결에 참여하지 않는다고 말함으로써 해결합니다. 당신은 사용 SFINAE하여 동일한 작업을 수행 할 수 있습니다 std::iterator_traits<InputIterator>::value_type이 존재하지 않는

이제
template <typename InputIterator, 
    typename ValueType = typename std::iterator_traits<InputIterator>::value_type> 
vector (InputIterator first, InputIterator last, 
     const allocator_type& alloc = allocator_type()); 

는 오버로드 확인은 템플릿 인수 대체하고 다른 하나를 대신 선택됩니다 동안 과부하를 무시합니다.

+0

죄송합니다!위의 코드를 편집했습니다. "ints"를 템플릿 매개 변수로 입력하려고 의도 한 것이 아니며 2 개의 반복자로되어 있습니다. –

+0

@ user3833701 당신은 여전히 ​​같은 문제가 있습니다. '벡터 lst (10, 5);에서 호출 된 첫 번째 생성자가 아닙니다. 템플릿 일치입니다. 더 나은 일치이기 때문입니다. – jrok

+0

@ user3833701 수정 된 답변보기 – jrok