#c #boost #boost-range #boost-adaptors
Вопрос:
Я хочу использовать boost boost::adaptor::map_values
для построения вектора всех значений a std::map
. Возьмите этот пример кода (или попробуйте его в Godbolt):
#include <boost/range/adaptors.hpp>
#include <boost/range/adaptor/map.hpp>
std::vector<int> getValueVector(const std::map<int, int> amp; 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);
}
GCC жалуется:
error: no match for call to '(const boost::range_detail::map_values_forwarder) (const std::map<int, int>amp;)'
Все примеры и вся документация, которые я могу найти, когда-либо используют адаптеры boost только внутри операторов, которые принимают диапазоны (например, на основе диапазонов для циклов или boost::copy
), но никогда в операторах, которым нужны пары итераторов, таких как std::vector
конструктор.
Согласно GCC, проблема здесь в том, что map_values
это неприменимо к std::map<int, int>
. Тем не менее, это буквально единственный пример, приведенный в документах, поэтому я почти уверен, что std::map<int, int>
для этого все должно быть в порядке map_values
.
Что здесь не так?
P.S.: Я знаю, что существует множество других способов элегантного построения вектора по значениям карты. Я хочу знать, почему этот код не работает. Кроме того, этот подход имеет дополнительное преимущество гарантированного RVO вместо «вероятно, NRVO», которое есть у большинства других решений, которые я могу придумать.
Комментарии:
1. Вы неправильно его применяете. Я верю, что это должно быть что-то вроде
m | boost::adaptors::map_values;
2. В документации говорится, что
m | boost::adaptors::map_values
иboost::adaptors::map_values(m)
должно быть эквивалентно. Но на самом деле, похоже, это работает. Странный.3. @LukasBarth я думаю
m | boost::adaptros::map_values
, иboost::adaptors::values(m)
они эквивалентны. Обратите внимание на другое название
Ответ №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> amp; 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 autoamp; e : v) std::cout << e << " ";
}
Есть ожидаемый результат:
2 4 6
Комментарии:
1. О, ты прав. Варианты на
operator|
основе и на основе вызова функций называются по-разному. Спасибо!