迭代器成员行为

发布于 2024-09-12 21:18:59 字数 599 浏览 3 评论 0原文

我期待下面的第二个断言能够通过。我请求你的帮助。

编辑:当我到处都是 poss 而不是某些地方的 poss_a 时,它不起作用。

#include <vector>
#include <cassert>

class Sampler
{
public:
 std::vector<int*> poss;
 std::vector<int*>::const_iterator poss_it;
 Sampler(std::vector<int*> poss_a) : poss(poss_a), poss_it(poss.begin())
 {
  assert( (poss[0]) == (*poss_it) ); //passes
 }
};

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

 return 0;
}

I was expecting the second assert in the following to pass. I'm asking for your help.

Edit: It didn't work when I had poss everywhere instead of poss_a in some places.

#include <vector>
#include <cassert>

class Sampler
{
public:
 std::vector<int*> poss;
 std::vector<int*>::const_iterator poss_it;
 Sampler(std::vector<int*> poss_a) : poss(poss_a), poss_it(poss.begin())
 {
  assert( (poss[0]) == (*poss_it) ); //passes
 }
};

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

 return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

云朵有点甜 2024-09-19 21:18:59

初始化列表中的 poss_it(poss.begin()) 行从作为构造函数输入的 poss 中提取一个迭代器,而不是作为类的字段的迭代器。

这是一个范围问题。当您在构造函数中时,这很好,因为您的迭代器是指向函数输入的指针。然而,当您离开构造函数时,它指向内存中的同一位置,但现在您不知道该位置有什么。

您应该更改构造函数中输入变量的名称。您想要一个能够执行此操作的:

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

而您当前正在执行的操作是:

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

The poss_it(poss.begin()) line in your initializer list is pulling an iterator from the poss that is the input to the constructor, not the one that is a field of the class.

This is a scope issue. When you're in the constructor, it's fine, because your iterator is a pointer to the input to the function. When you leave the constructor however, it's pointing to the same spot in memory but now you have no idea what's at that location.

You should change the name of the input variable in the constructor. You want one that does this:

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

Whereas what your current one is doing is this:

Sampler(std::vector<int*> input) : poss(input), poss_it(input.begin())
瘫痪情歌 2024-09-19 21:18:59

可能会对覆盖实例变量的局部变量感到困惑,请尝试

#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;
}

Probably getting confused over the local variables overriding the instance variables, try

#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;
}
夏末 2024-09-19 21:18:59

您本质上是在调用未定义的行为,因为 sampler.poss_it 是一个 std::vector 对象的迭代器,该对象在第二个 assert< 之前被破坏。 /code> 已执行。

问题出在线上:

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

poss(poss) 的第一个 poss 引用了 Sampler 对象的 poss成员,poss(poss)的第二个poss引用了poss参数,poss的>poss_it(poss.begin()) 再次引用 poss 参数(不是 poss 成员)。 poss 参数在构造函数末尾超出范围,因此 poss 参数被破坏,这意味着 poss_it 迭代器不再有效的。

为了避免此类问题,C++ 程序员几乎总是避免隐藏变量。另外,复制构造函数可能应该采用 const 引用(以避免潜在大对象的值传递):

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

You are essentially invoking undefined behavior because sampler.poss_it is an iterator into a std::vector<int*> object that was destructed before the second assert was executed.

The problem was on the line:

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

where the first poss of poss(poss) refers to the Sampler object's poss member, the second poss of poss(poss) refers to the poss parameter, and the poss of poss_it(poss.begin()) refers again to the poss parameter (not the poss member). The poss parameter goes out of scope at the end of the constructor, so the poss parameter is destructed, meaning that the poss_it iterator is no longer valid.

To avoid this type of problem, C++ programmers almost always avoid shadowing variables. Also, a copy constructor should probably take a const-reference (to avoid pass-by-value for potentially large objects):

Sampler(const std::vector<int*>& poss_) : poss(poss_), poss_it(poss.begin())
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文