Поведение члена итератора - PullRequest
2 голосов
/ 07 августа 2010

Я ожидал, что второе утверждение в следующем пройдет.Я прошу вашей помощи.

Редактировать: Это не сработало, когда у меня была возможность везде, а не poss_a в некоторых местах.

Ответы [ 3 ]

1 голос
/ 07 августа 2010

Строка poss_it(poss.begin()) в вашем списке инициализатора вытягивает итератор из опоса, который является входом для конструктора, а не из поля класса.

Это проблема объема. Когда вы в конструкторе, это нормально, потому что ваш итератор является указателем на входные данные функции. Однако, когда вы покидаете конструктор, он указывает на то же место в памяти, но теперь вы не знаете, что находится в этом месте.

Вы должны изменить имя входной переменной в конструкторе. Вы хотите тот, который делает это:

Sampler(std::vector<int*> input) : poss(input), poss_it(poss.begin())

Принимая во внимание то, что делает ваш нынешний:

Sampler(std::vector<int*> input) : poss(input), poss_it(input.begin())
1 голос
/ 07 августа 2010

По сути, вы вызываете неопределенное поведение, потому что sampler.poss_it является итератором объекта std::vector<int*>, который был уничтожен до выполнения второго assert.

Проблема была в строке:

Sampler(std::vector<int*> poss) : poss(poss), poss_it(poss.begin())

, где первый poss из poss(poss) относится к poss члену Sampler объекта, второй poss из poss(poss) относится к параметру poss, а possзначение poss_it(poss.begin()) снова относится к параметру poss ( не элемент poss).Параметр poss выходит из области видимости в конце конструктора, поэтому параметр poss уничтожается, что означает, что итератор poss_it больше не действителен.

Чтобы избежать проблем такого типа,Программисты C ++ почти всегда избегают теневых переменных.Кроме того, конструктор копирования, вероятно, должен принимать константную ссылку (чтобы избежать передачи по значению для потенциально больших объектов):

Sampler(const std::vector<int*>& poss_) : poss(poss_), poss_it(poss.begin())
1 голос
/ 07 августа 2010

Возможно, запутались из-за локальных переменных, переопределяющих переменные экземпляра, попробуйте

#include <vector>
#include <cassert>

class Sampler
{
public:
    std::vector<int*> poss;
    std::vector<int*>::const_iterator poss_it;
    // THIS IS THE LINE I CHANGED
    Sampler(std::vector<int*> aPoss)    : poss(aPoss), poss_it(poss.begin())
    {
        assert( (poss[0]) == (*poss_it) ); //passes
    }
};

int main()
{
    int someInt;
    std::vector<int*> poss(1, &someInt);
    Sampler sampler(poss);
    assert( ((sampler.poss)[0]) == (*(sampler.poss_it)) ); //fails

    return 0;
}
...