【问题标题】:C++ STL; Iterate over class which contains STL container?C++ STL;迭代包含 STL 容器的类?
【发布时间】:2017-08-17 09:57:40
【问题描述】:

我有线性代数课程,特别是向量和矩阵。其中包含 std::vectors(或 std::maps)作为它们的“数据”字段。

在基于范围的 for 循环中迭代这些很容易。但我想将这些字段设为私有,并使对自定义类的迭代更加自然,这样我就可以对类本身进行基于范围的 for 循环。

我尝试查看 std::vector.begin() 等的函数定义。然后我尝试以这样一种方式实现它,即所有迭代器对象都从 std::vector 字段转发,但无济于事。当我尝试使用以下示例迭代我的类的常量实例时;

int main() {

    AlgebraLib::Vector A(4, true);
    A[0] = 4;
    A[1] = 5;
    A[2] = 6;
    A[3] = 7;

    for (auto &&item : A) {
        std::cout << item << std::endl;
    }

    const AlgebraLib::Vector B = A;

    for (auto &&item : B) {
        std::cout << item << std::endl;
    }

    return EXIT_SUCCESS;
}

...我收到以下编译器错误;

error: passing ‘const AlgebraLib::Vector’ as ‘this’ argument discards qualifiers [-fpermissive]
 for (auto &&item : B) {

基本上,所有的迭代器都是这样定义的:

std::vector<double>::iterator Vector::begin() {
    return _VectorContents.begin();
}

std::vector<double>::iterator Vector::end() {
    return _VectorContents.end();
}

std::vector<double>::reverse_iterator Vector::rbegin() {
    return _VectorContents.rbegin();
}

std::vector<double>::reverse_iterator Vector::rend() {
    return _VectorContents.rend();
}

std::vector<double>::const_iterator Vector::cbegin() const noexcept{
    return _VectorContents.cbegin();
}

std::vector<double>::const_iterator Vector::cend() const noexcept{
    return _VectorContents.cend();
}

std::vector<double>::const_reverse_iterator Vector::crbegin() const noexcept{
    return _VectorContents.crbegin();
}

std::vector<double>::const_reverse_iterator Vector::crend() const noexcept{
    return _VectorContents.crend();
}

在我的头文件 Vector.hpp 中:

    // Iterators
    std::vector<double>::iterator begin();

    std::vector<double>::iterator end();

    std::vector<double>::reverse_iterator rbegin();

    std::vector<double>::reverse_iterator rend();

    std::vector<double>::const_iterator cbegin() const noexcept;

    std::vector<double>::const_iterator cend() const noexcept;

    std::vector<double>::const_reverse_iterator crbegin() const noexcept;

    std::vector<double>::const_reverse_iterator crend() const noexcept;

我觉得我在这里遗漏了什么?我对 C++ 比较陌生,目前我在使用 C++11。

【问题讨论】:

  • 什么是row_VectorContents 是什么?请创建Minimal, Complete, and Verifiable Example 向我们展示。
  • 在不相关的注释上,所有以下划线开头并后跟大写字母的符号(例如_VectorContents)在所有范围内都保留。请参阅this old question and its answers 了解更多信息。
  • 很抱歉,应该做一个更好的例子。感谢您对下划线的评论,我确实将它用于我的所有成员变量。

标签: c++11 vector stl iterator


【解决方案1】:

问题在于 Bconst,但 range-for 循环仅使用 beginend(不是 cbegincend)以及您的 beginend 函数没有const 的重载。这是一个问题,因为只有标记为 const 的函数才能在 const 对象上调用。

解决方案很简单:只需添加这样的重载

std::vector<double>::const_iterator begin() const;

std::vector<double>::const_iterator end() const;

这些重载的实现将与非常量函数的实现相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-17
    • 2013-04-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-22
    • 1970-01-01
    • 2011-12-25
    相关资源
    最近更新 更多