在 stl 映射和列表 (c++) 上进行迭代的泛型循环

Generic loop that iterates on both stl map and list (c++)

本文关键字:迭代 循环 泛型 映射 stl 列表 c++      更新时间:2023-10-16

有没有办法编写一个通用循环,它迭代stl map(关联容器(和列表(非关联容器(的值。

template<typename T>
void foo(T &t)
{
    for (auto iter = t.begin(); iter != t.end(); ++iter)
    {
        printf("%dn", *iter); // will work for std::list<int> but not for std::map<int, int>
    }
}

谢谢

要使其适用于 std::map - 使用来自 boost 的正确适配器:

foo(someMap | boost::adaptors::map_values);

你也可以使用 Eric Niebler 的 ranges-v3

foo(someMap | ranges::values); 

如果您不能使用提升/范围 - 请使用某种特征:

template <typename ValueType>
struct ValueGetter
{ 
    static Value& get(ValueType& value)
    {
        return value;
    }
};
template <typename Key, typename Value>
struct ValueGetter<std::pair<const Key, Value>>
{ 
    using ValueType = std::pair<const Key, Value>; 
    static Value& get(ValueType& value)
    {
        return value.second;
    }
};
template <typename ValueType>     
auto& getValue(ValueType& value)
{
    return ValueGetter<Value>::get(value);
}
template<typename T>
void foo(T &t)
{
    for (auto iter = t.begin(); iter != t.end(); ++iter)
    {
        printf("%dn", getValue(*iter)); 
    }
}

实际上,已经有 std::for_each ( #include <algorithm> ( 用于此类目的。您可以使用适当的处理程序来喂养它,例如以 lambda 的形式:

std::vector<int> v;
std::map<int, double> m;
std::for_each(v.begin(), v.end(), [](auto i) { printf("%dn", i); });
std::for_each(m.begin(), m.end(), [](auto const& i) { printf("%d %fn", i.first, i.second); });

我确实喜欢阿空加瓜的显示方式,在大多数情况下,这将是我最喜欢的选择。

为了使它更清晰并填补我的评论的空白。作者在这里发布的循环还可以。在这种情况下,唯一的问题是关于printf()。为了解决这个问题,我建议像重载流运算符((这样的东西,以便能够打印出std::map

ostream& operator<<(ostream& os, pair<string, int> it){
    os << it.first << " => " << it.second;
}

正如您可能已经意识到的那样,在 std::map 的情况下,迭代器是这对。请注意,您无需为std::list指定 ,泛型循环可能如下所示

template<typename T>
void foo(T &t){
    for(auto it=t.begin(); it=t.end(); ++it){
        cout << *it << endl;
    }
}

这与问题中的内容很好,除了printf() => cout.在这里,您还可以使用基于范围的循环

template<typename T>
void foo(T &t){
    for(auto it : t)
        cout << it << endl;
}

最后for_each()函子或 lambda 表达式的一侧。