“Универсальный” итератор в C++

Как инструментарий упоминает выше, Apache палата общин, IO является способом пойти, конкретно FileUtils. copyFile () ; это обрабатывает весь тяжелый подъем для Вас.

И как постскриптум, обратите внимание, что последние версии FileUtils (такие как эти 2.0.1 выпуска) добавили использование NIO для копирования файлов; NIO может значительно увеличить копирующую файл производительность в значительной части, потому что стандартные программы NIO задерживают копирование непосредственно к ОС/файловой системе, а не обрабатывают его путем чтения и записи байтов через уровень Java. Таким образом, при поиске производительности могло бы стоить проверить использование последней версии FileUtils.

13
задан nos 9 July 2009 в 13:53
поделиться

7 ответов

template<class InputIterator>
void add_all_msgs(InputIterator iter);

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

std::deque<Message> deq;
add_all_msgs(deq.begin());
7
ответ дан 1 December 2019 в 20:43
поделиться

Если вы хотите, чтобы компилятор проверял, действительно ли итератор ссылается на объекты Message , вы можете использовать следующий прием.

template <typename InputIterator, typename ValueType>
struct AddAllMessages { };

template <typename InputIterator>
struct AddAllMessages<InputIterator, Message> {
  static void execute(const InputIterator &it) {
    // ...
  }
};

template <typename InputIterator>
void add_all_msgs(const InputIterator &it) {
  AddAllMessages<InputIterator, 
                 typename std::iterator_traits<InputIterator>::value_type>::execute(it);
}
5
ответ дан 1 December 2019 в 20:43
поделиться
template <typename Iterator>
void add_all_messages(Iterator first, Iterator last)

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

vector<message> v;
add_all_messages(v.begin(), v.end());

Вам нужно указать конец, иначе вы не будете знать, когда остановиться! Это также дает вам возможность добавлять только поддиапазон контейнера.

13
ответ дан 1 December 2019 в 20:43
поделиться

Если вы не хотите создавать шаблоны для функции add_all_msgs, вы можете использовать adobe :: any_iterator :

typedef adobe::any_iterator<Message, std::input_iterator_tag> any_message_iterator;
void add_all_msgs(any_message_iterator begin, any_message_iterator end);
2
ответ дан 1 December 2019 в 20:43
поделиться

Трудно иметь динамический полиморфизм с итераторами в стиле C ++. operator ++ (int) возвращает значение по значению, с которым невозможно справиться: у вас не может быть виртуальной функции-члена, которая возвращает * this по значению без ее нарезки.

Если возможно, , Я рекомендую использовать шаблоны, как говорят все.

Однако, если вам действительно нужен динамический полиморфизм, например, потому что вы не можете раскрыть реализацию add_all_msgs как шаблон, тогда я думаю, вы могли бы притвориться Java, например это:

struct MessageIterator {
    virtual Message &get() = 0;
    virtual void next() = 0;
    // add more functions if you need more than a Forward Iterator.
    virtual ~MessageIterator() { };  // Not currently needed, but best be safe
};

// implementation elsewhere. Uses get() and next() instead of * and ++
void add_all_msgs(MessageIterator &it);

template <typename T>
struct Adaptor : public MessageIterator {
    typename T::iterator wrapped;
    Adaptor(typename T::iterator w) : wrapped(w) { }
    virtual Message &get() {
        return *wrapped;
    }
    virtual void next() {
        ++wrapped;
    }
};

int main() {
    std::deque<Message> v;
    Adaptor<std::deque<Message> > a(v.begin());
    add_all_msgs(a);
}

Я проверил, что это компилируется, но не тестировал и никогда раньше не использовал этот дизайн. Я также не стал беспокоиться о константе - на практике вы, вероятно, захотите const Message & get () const . И на данный момент адаптер не знает, когда остановиться, но и код, с которого вы начали, тоже не знает, поэтому я это тоже проигнорировал. В основном вам понадобится функция hasNext , которая сравнивает завернутый с конечным итератором, предоставленным конструктору.

Возможно, вы сможете что-то сделать с помощью функции шаблона и константных ссылок, так что клиенту не нужно знать или объявлять об этом неприятном типе адаптера.

Не нужно знать или объявлять об этом неприятном типе адаптера.

Не нужно знать или объявлять об этом неприятном типе адаптера.

[Edit: если подумать, наверное, лучше иметь шаблон функции-заглушки add_all_msgs , который помещает свой параметр в адаптер, а затем вызывает real_add_all_msgs . Это полностью скрывает адаптер от клиента.]

1
ответ дан 1 December 2019 в 20:43
поделиться
#include <deque>
#include <vector>
#include <list>
#include <string>
using namespace std;

template<typename T>
void add_all_msgs(T &iter)
{

}

int _tmain(int argc, _TCHAR* argv[])
{
    std::deque<string>::iterator it1;
    std::vector<string>::iterator it2;
    std::list<string>::iterator it3;

    add_all_msgs(it1);
    add_all_msgs(it2);
    add_all_msgs(it3);


    return 0;
}
0
ответ дан 1 December 2019 в 20:43
поделиться

Немного проще, чем вышеприведенное (в том, что он использует существующие библиотеки):

#include <boost/static_assert.hpp> // or use C++0x static_assert
#include <boost/type_traits/is_same.hpp>

template <typename InputIterator>
void add_all_msgs( InputIterator it ) {
    BOOST_STATIC_ASSERT(( boost::is_same<
        typename std::iterator_traits<InputIterator>::value_type,
        Message>::value ));
    // ...
1
ответ дан 1 December 2019 в 20:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: