【问题标题】:c++ std::list compile issue? related to list.end() and list.end() - 1c++ std::list 编译问题?与 list.end() 和 list.end() 相关 - 1
【发布时间】:2019-05-22 20:47:45
【问题描述】:

在下面的代码中。

int main() {
    list<int> m_list;
    m_list.push_back(1);
    list<int>::iterator it1 = (--m_list.end());   // it works, *it1 return 1;
    list<int>::iterator it2 = (m_list.end() - 1); // compile issue? 
}

有人解释为什么在列表 (m_list.end() - 1) 中有编译问题吗?为什么 (--m_list.end()) 可以? 如果我们换成其他的,vector,string。这两种情况都有效。

int main() {
    vector<int> m_vector;
    m_vector.push_back(1);
    vector<int>::iterator it1 = (--m_vector.end());   // both work
    vector<int>::iterator it2 = (m_vector.end() - 1); // both work 
}

【问题讨论】:

标签: c++ list


【解决方案1】:

这背后的原因是 list::end() 返回了一个不支持这种操作的双向迭代器

来源:

http://www.cplusplus.com/reference/iterator/BidirectionalIterator/

另一方面,vector::end() 和 string::end() 返回一个支持这种操作的随机访问迭代器

http://www.cplusplus.com/reference/iterator/RandomAccessIterator/

编辑:

如果你真的想完成任务,使用std::prev()函数

list<int>::iterator it2 = (std::prev(m_list.end(), 1));

正如Pete Becker 所建议的,“std::prev 的第二个参数的默认值为 1”

所以,你也可以这样做:

list<int>::iterator it2 = (std::prev(m_list.end()));

【讨论】:

  • std::prev 的第二个参数默认为 1,因此只需要 std::prev(m_list.end())
  • 感谢@PeteBecker 的建议。您的观点已包含在答案中。
【解决方案2】:

有人解释为什么在列表 (m_list.end() - 1) 中有编译问题?

因为列表迭代器不支持随机访问。只有随机访问迭代器才能保证支持operator-(和operator+)。

为什么 (--m_list.end()) 可以?

因为双向迭代器支持operator--(和operator++)。列表迭代器是双向的。

如果我们换成其他的,vector,string。这两种情况都有效。

向量和字符串都有随机访问迭代器。

【讨论】:

  • 惊人的答案。
猜你喜欢
  • 2013-02-13
  • 1970-01-01
  • 2011-05-27
  • 1970-01-01
  • 2021-08-03
  • 2011-09-15
  • 1970-01-01
  • 2018-10-17
  • 2019-12-24
相关资源
最近更新 更多