2013-05-15 5 views
0

У меня есть образец большого целочисленного класса. Он содержит динамический массив цифр, которые содержат большое целое число. Я хотел бы построить объекты этого класса, используя 2 итератора (начало и конец), чтобы я мог передавать цифры из std :: vector или std :: list.C++: Как построить объект с двумя итераторами?

Некоторые псевдокод иллюстрирующую мою мысль:

BigInteger(std::iterator begin, std::iterator end); 
... 

Использование:

std::vector<int> v; 
// fill vector with digits 
... 
BigInteger b(v.begin(), v.end()); 

Вопрос заключается в том: как правильно объявить такой конструктор? Также возможно?

Спасибо!

+2

В качестве шаблона ?! –

+2

Точно так же 'vector' делает это: http://en.cppreference.com/w/cpp/container/vector/vector –

+0

, поэтому нет способа использовать некоторый« обычный тип итератора »? – DaddyM

ответ

2

Используйте шаблон конструктор:

template<class InputIterator> 
BigInteger(InputIterator begin, InputIterator end) 

Это должно быть использовано как:

std::vector<int> v; //Fill with values  
BigInteger(v.begin(), v.end()); 
+0

Итак, не существует способа использовать некоторый «обычный тип итератора»? – DaddyM

+0

Мне нужно использовать ссылку на итератор вместо простого копирования объекта итератора? Будет ли это возможным и более эффективным? – DaddyM

+2

Ну, InputIterator - обычный тип итератора. Вы можете просто использовать Итератор, если хотите. Ссылка работает, но, по-видимому, общепринятой практикой является использование итераторов не по ссылке. Проверьте этот ответ: http: // stackoverflow.com/questions/1104035/generic-iterator-in-c –

1

Вы не можете использовать это просто!

Если объявлять типы итераторов в качестве шаблонов, вы можете иметь это:

template <typename Itr> 
BigInteger(Itr begin, Itr end) 
{ 
} 

или

BigInteger(std::vector<int>::iterator begin, std::vector<int>::iterator end) 
{ 
} 

Но, как насчет std::iterator. Ну, std::iterator шаблонный класс, и вы должны обеспечить его параметры, и вы должны извлечь из него

class MyItr : public std::iterator<std::input_iterator_tag, int> 
{ 
... 
}; 

BigInteger(MyItr begin, MyItr end) 
{ 
} 

Это длинная история! Возможное определение std::iterator является

template<typename _Category, typename _Tp, typename _Distance = ptrdiff_t, 
      typename _Pointer = _Tp*, typename _Reference = _Tp&> 
    struct iterator 
    { 
     typedef _Category iterator_category; 
     typedef _Tp  value_type; 
     typedef _Distance difference_type; 
     typedef _Pointer pointer; 
     typedef _Reference reference; 
    }; 

Как вы можете видеть, это просто пустой класс с некоторыми typedef с. Итак, вы должны реализовать operator*(), operator->(), begin(), end(), ... для производного итератора.

+0

, пожалуйста, скажите мне, что мне следует реализовать вместо ...? – DaddyM

+0

@DaddyM: Использование шаблонов для передачи итераторов является обычным и простым способом. 'std :: iterator' - это не прямой путь, вы должны переопределить многие члены, это просто пустой класс. – deepmax