不明白 std::iterator 在列表初始化中如何工作

问题描述 投票:0回答:1

我在使用

std::vector::iterator
时遇到问题。首先我定义了一个
struct

template <typename T>
struct VecIter {
  VecIter(std::vector<T>::iterator &&it_, size_t remain_):
    it(it_), remain(remain_) {}

  std::vector<T>::iterator &it;
  size_t remain;

  T& operator * () {
    return *it;
  }
};

它只是常规迭代器的包装。这是一个测试类:

template <typename T>
class testA {
  public:
    testA(std::vector<T> &a) {
      stack.push_back({a.begin(), a.size()});
    }

    std::vector<VecIter<T>> stack;
};

构造函数采用

std::vector
作为输入并初始化我们的迭代器包装器。测试部分来了:

TEST(TestIterator, test_iter_in_stack) {
  std::vector<int> a{3, 2, 1};

  testA<int> sol(a);
  auto x = sol.stack[0];
 
  auto it = x.it;  // extract the iterator
  cout << *it << "\n";  // segmentation fault here...
  it++;
  cout << *it << "\n";
}

我的问题是为什么这里的

*it
会导致分段错误?我怀疑列表初始化
stack.push_back({a.begin(), a.size()})
没有成功将迭代器传入。

我希望测试应该打印出

3
2
。欢迎任何评论。谢谢!

c++ iterator
1个回答
0
投票

VecIter::it
是对
a.begin()
返回的临时对象的悬空引用。您应该将
std::vector<T>::iterator &it
更改为
std::vector<T>::iterator it
。一般来说,迭代器可能只不过是一个指针,通过引用传递和存储它们不太可能是必要的,标准库通常通过值传递它们,例如在
std::vector
构造函数中

© www.soinside.com 2019 - 2024. All rights reserved.