为什么我不能在基于范围的循环之外使用 boost::adaptor::map_values?

Why can't I use boost::adaptor::map_values outside a ranged-based loop?

提问人:Lukas Barth 提问时间:4/27/2021 最后编辑:cpplearnerLukas Barth 更新时间:7/14/2021 访问量:260

问:

我想使用 boost 来构造一个 .以这个示例代码为例(或在 Godbolt 上尝试一下):boost::adaptor::map_valuesstd::map

#include <boost/range/adaptors.hpp>
#include <boost/range/adaptor/map.hpp>

std::vector<int> getValueVector(const std::map<int, int> & m)
{
    auto valueRange = boost::adaptors::map_values(m);
    return std::vector<int>(valueRange.begin(), valueRange.end());
}

int main() {
    std::map<int, int> my_map;
    getValueVector(my_map);
}

海湾合作委员会抱怨:

error: no match for call to '(const boost::range_detail::map_values_forwarder) (const std::map<int, int>&)'

我能找到的所有示例和所有文档都只在接受范围的语句中使用升压适配器(例如基于范围的 for 循环或),从不在需要迭代器对的语句中使用,例如 的构造函数。boost::copystd::vector

根据 GCC 的说法,这里的问题是不适用于 .但是,这实际上是文档给出的唯一示例,所以我很确定这应该可以。map_valuesstd::map<int, int>std::map<int, int>map_values

这里有什么不对劲?

P.S.:我知道还有无数其他方法可以从地图的值优雅地构建向量。我想知道为什么这段代码不起作用。此外,这种方法还有一个额外的好处,即有保证的 RVO 而不是“可能是 NRVO”,这是我能想到的大多数其他解决方案。

C++ boost-range 升压适配器

评论

1赞 ALX23z 4/27/2021
你没有正确应用它。我相信它应该是这样的m | boost::adaptors::map_values;
0赞 Lukas Barth 4/27/2021
文档指出,并且应该是等效的。但事实上,这似乎奏效了。奇怪。m | boost::adaptors::map_valuesboost::adaptors::map_values(m)
1赞 463035818_is_not_an_ai 4/27/2021
@LukasBarth我认为并且是等价的。请注意不同的名称m | boost::adaptros::map_valuesboost::adaptors::values(m)

答:

2赞 463035818_is_not_an_ai 4/27/2021 #1

我不熟悉范围,但这可能是一个答案,所以我将其作为答案发布。

在顶部,他们写道

Syntax      Code

Pipe        rng | boost::adaptors::map_values
Function    boost::adaptors::values(rng) 

事实上,当我将您的代码更改为以下代码时:

#include <boost/range/adaptors.hpp>
#include <boost/range/adaptor/map.hpp>
#include <iostream>

std::vector<int> getValueVector(const std::map<int, int> & m)
{
    auto valueRange = boost::adaptors::values(m);
    return std::vector<int>(valueRange.begin(), valueRange.end());
}

int main() {
    std::map<int, int> my_map{{1,2},{3,4},{5,6}};
    auto v = getValueVector(my_map);
    for (const auto& e : v) std::cout << e << " ";
}

有预期的输出

2 4 6 

评论

0赞 Lukas Barth 4/27/2021
哦,你是对的。基于 -的变体和基于函数调用的变体的名称不同。谢谢!operator|