Как определить, был ли изменен выходной итератор - PullRequest
0 голосов
/ 20 августа 2009

У меня есть функция шаблона, которая принимает следующую форму:

template < class ITER1, class ITER2 >
bool example(ITER1 Input1, ITER1 Input2, ITER2 Output)
{
    ITER2 OrigOutput(Output);

    // ...

    std::copy(Input1, Input2, Output);

    return (OrigOutput != Output);
}

И я звоню example() вот так:

std::vector < int > Input;
std::set < int > Output;

if (example(Input.begin(), Input.end(), inserter(Output, Output.begin())))
{
    ...
}

Я бы хотел example() вернуть true, если элементы были вставлены в Output, однако я получаю ошибку компиляции (msvc 2008):

Error 1 error C2678: binary '!=' : no operator found which takes a left-hand 
operand of type 'std::insert_iterator<_Container>' (or there is no acceptable 
conversion)

Есть ли способ определить, были ли какие-либо элементы вставлены в выходной итератор для возврата правильного значения bool?

Ответы [ 3 ]

4 голосов
/ 20 августа 2009

Напишите итератор-обертку, который переходит к другому итератору, который вы создадите из своего итератора вставки. Затем ваш делегат может установить для члена modified значение true в методе operator=.

Что-то вроде этого:

template<typename ITER>
class ModifiedIterator : public std::iterator<std::output_iterator_tag, void, void, void, void>
{
protected:
    typedef ITER Iter;
    Iter iter;
    bool& isModified;

public:
    explicit ModifiedIterator (Iter i, bool& isMod)
    : iter(i), isModified (isMod)
    {}

    template<typename T>
    ModifiedIterator& operator= (const T& value)
    {
        iter = value;
        ++iter;
        isModified = true;
        return *this;
    }

    ModifiedIterator& operator* () { return *this; }
    ModifiedIterator& operator++ () { return *this; }
    ModifiedIterator operator++ (int) { return *this; }
};
1 голос
/ 20 августа 2009

У вас есть как минимум следующие две опции:

  1. Напишите свою собственную версию inserter, которая принимает дополнительный логический параметр ссылки в качестве аргумента, который устанавливается в значение true, если cont.insert (...).second имеет значение true.
  2. Перед оператором 'if' в коде вызывающей стороны сохраните размер контейнера. Если после вызова есть больше элементов, то вы знаете, что при копировании вставлены элементы.

Второй вариант имеет потенциальные соображения производительности, если стоимость размера не O (1).

1 голос
/ 20 августа 2009

OutputIterators не позволяют этого. Но в вашем случае, что мешает вам вернуть Input1 != Input2?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...