【问题标题】:Custom iterator returning std::pair of custom container elements (no boost)自定义迭代器返回 std::pair 自定义容器元素(无提升)
【发布时间】:2018-02-05 20:52:17
【问题描述】:

我有一个尽可能简化的类并用于演示目的。它看起来很简单:

#include <iostream>
#include <vector>


class Simple
{
private:
    std::vector<std::size_t> indices;
    std::vector<int> values;
public:
    void insert(std::size_t index, int value)
    {
        indices.push_back(index);    
        values.push_back(value);
    }
    int at(std::size_t index)
    {
        return values[indices[index]];    
    }
};

int main()
{
    Simple s;
    s.insert(10, 100);
    std::cout << s.at(10) << std::endl;
    return 0;
}

我要实现的是迭代此容器的元素并在每次迭代时获取 std::pair,其first 元素将是来自indices 成员的值,其second 元素将是一个值来自values 成员。比如:

Simple s;
s.insert(10, 100);
for (std::pair<std::size_t, int> node : s)
{
    std::cout << node.first << " " << node.second << std::endl; // expect to print 10 100
}

我对迭代器真的很陌生。我知道如何遍历标准容器并获取它们的值。我什至知道如何遍历我的Simple 容器并在每次迭代时从values 成员中获取价值。我可以这样做:

//new member functions in Simple class
auto begin()
{
    std::begin(values);
}

auto end()
{
    std::end(values);
}

但我不知道如何在每次迭代中创建一些新的数据类型并将其返回给客户端代码。

【问题讨论】:

  • main 中的示例代码将产生未定义的行为。看起来您正在尝试制作地图,但没有完全正确。您不只是使用 STL 地图有什么原因吗?
  • 我知道它看起来像地图,但正如我所说,我做了一个简单的例子只是为了演示。
  • 这就是你要找的,也许是:stackoverflow.com/questions/8511035/…
  • @Rakete1111。类似的东西,但没有提升依赖关系。
  • 基于range 的答案没有得到提升。它甚至可能在您的标准库中为std::experimental::ranges

标签: c++


【解决方案1】:

请注意,您尝试遍历一个没有任何抽象的类。我的意思是,只有当你“制作”一个向量或你可以迭代的不同数据结构时,你才能迭代它。

class Simple : public vector<std::pair<std::size_t, int>> { /*...*/ };

一旦你用这样的语法声明了一个class,你就可以把它当作一个对的向量来处理。您还可以声明自己的自定义方法。

您现在可以:

Simple simple;
simple.push_back({10, 100});
for (auto element : simple) {
    std::cout << element.first << " " << element.second << std::endl;
}

我推荐你一些reading 在这种实现中。有时它可以节省很多工作!你知道他们怎么说,为什么要重新发明轮子?

请记住,at(10) 方法将返回向量位置 10 上的元素。在您的示例中,您尝试从 out_of_range 位置读取。

也许您对map 感兴趣,它包含一个key 和一个value。从您的示例来看,您似乎并没有试图保持数据结构的排序。如果是,您可以使用map 而不是unordered_map。您可以使用 find 方法从键中检索值:

#include <unordered_map>

/* ... */

unordered_map<std::size_t, int> simple;    
simple.insert({10, 100});

auto it = simple.find(10);
if (it != simple.end()) {
    std::cout << "Found value from key: " << *it << std::endl;
} else {
    std::cout << "Your map doesn't contain such key!" << std::endl;
}

请注意,map 不允许具有相同值的多个键。但是multimap 可以。

【讨论】:

  • 可能我没有过分强调,但我的例子不是关于地图,多地图等。我提供一个例子只是为了说明目的。我的 Simple 类中可以有三个或更多向量,如果我知道如何从迭代器中获取一对,我可以对其进行泛化并返回一个元组。所以,我的问题纯粹是关于迭代器。
猜你喜欢
  • 2013-02-17
  • 1970-01-01
  • 2020-04-28
  • 2021-09-15
  • 1970-01-01
  • 2013-11-08
  • 2015-02-04
  • 2020-12-08
相关资源
最近更新 更多