C++ 如何将boost::range::sort()转换为boost::transformed\u范围?

C++ 如何将boost::range::sort()转换为boost::transformed\u范围?,c++,boost,boost-range,C++,Boost,Boost Range,我想基于foo的一个成员从向量中获取唯一的元素。我正在使用boost::adapters::transform选择成员,然后进行排序,然后使用boost::adapters::unique。我很难让这一步起作用。暂时抛开unique调用不谈,我已经尝试了下面的代码 而在#else部分使用基本迭代器类型的std::sort确实有效。我不明白为什么。在我的实际用例中,我还使用了boost::adapters::indirect和boost::adapters::filter(我更喜欢在排序之前进行过

我想基于
foo
的一个成员从
向量
中获取唯一的元素。我正在使用
boost::adapters::transform
选择成员,然后进行排序,然后使用
boost::adapters::unique
。我很难让这一步起作用。暂时抛开
unique
调用不谈,我已经尝试了下面的代码


而在
#else
部分使用基本迭代器类型的
std::sort
确实有效。我不明白为什么。在我的实际用例中,我还使用了
boost::adapters::indirect
boost::adapters::filter
(我更喜欢在排序之前进行过滤,或者至少尝试这样做,看看它是如何执行的),所以,这就是为什么在进行转换之前,我不简单地使用lambda谓词对
单词进行排序。

问题在于,您有一个无法交换的临时字符串视图。您可以使用以下方法修复代码:

auto asString = boost::adaptors::transform(words, +[](foo& x) -> std::string& {return x.bar;});


请注意,这样可以直接对字符串进行排序,而不是对类进行排序。

boost::swap(*asString.begin(),*asString.begin())失败。您不能。排序需要随机访问。@sehe transform()文档声称它返回的范围类型与它接收的范围类型相同,所以它应该是随机访问,对吗?啊,这说明
const foo&x
不能返回对
bar
的非常量引用。是否需要显式的
std::string&
?默认情况下,它将按值返回?在我的实际用例中,我发现const问题的原因不同。我真正的用例是使
boost::adapters::unique
在迭代器向量上工作到一个集合中,当然集合中的字符串不能交换,因此
.base()
方法无法工作。现在我在上面复制了一个迭代器sort/unique。@MattChambers:注意,
sort
也需要随机访问迭代器,因此不能与
filter
unique
视图一起使用。这很时髦,但不太可能是人们需要的,IYAM:在我的
unique
完成它的工作之前,我必须对它进行
排序
;我好不容易才发现这一点。:)但是,是的,我以前误读了过滤器文档;当给定一个随机访问范围时,它将返回一个双向范围。所以我会做变换->排序->过滤->独特。你用你的花式通用兰博达取笑我。我现在正在使用VS2013:令人恼火的是,P也不以合理的方式支持+前缀。
In file included from /usr/local/include/c++/6.3.0/bits/char_traits.h:39:0,
                 from /usr/local/include/c++/6.3.0/ios:40,
                 from /usr/local/include/c++/6.3.0/ostream:38,
                 from /usr/local/include/c++/6.3.0/iostream:39,
                 from main.cpp:1:
/usr/local/include/c++/6.3.0/bits/stl_algobase.h: In instantiation of 'void std::iter_swap(_ForwardIterator1, _ForwardIterator2) [with _ForwardIterator1 = boost::iterators::transform_iterator<std::__cxx11::basic_string<char> (*)(const foo&), __gnu_cxx::__normal_iterator<foo*, std::vector<foo> >, boost::iterators::use_default, boost::iterators::use_default>; _ForwardIterator2 = boost::iterators::transform_iterator<std::__cxx11::basic_string<char> (*)(const foo&), __gnu_cxx::__normal_iterator<foo*, std::vector<foo> >, boost::iterators::use_default, boost::iterators::use_default>]':
/usr/local/include/c++/6.3.0/bits/stl_algo.h:84:20:   required from 'void std::__move_median_to_first(_Iterator, _Iterator, _Iterator, _Iterator, _Compare) [with _Iterator = boost::iterators::transform_iterator<std::__cxx11::basic_string<char> (*)(const foo&), __gnu_cxx::__normal_iterator<foo*, std::vector<foo> >, boost::iterators::use_default, boost::iterators::use_default>; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
/usr/local/include/c++/6.3.0/bits/stl_algo.h:1918:34:   required from '_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = boost::iterators::transform_iterator<std::__cxx11::basic_string<char> (*)(const foo&), __gnu_cxx::__normal_iterator<foo*, std::vector<foo> >, boost::iterators::use_default, boost::iterators::use_default>; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
/usr/local/include/c++/6.3.0/bits/stl_algo.h:1950:38:   required from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size, _Compare) [with _RandomAccessIterator = boost::iterators::transform_iterator<std::__cxx11::basic_string<char> (*)(const foo&), __gnu_cxx::__normal_iterator<foo*, std::vector<foo> >, boost::iterators::use_default, boost::iterators::use_default>; _Size = long int; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
/usr/local/include/c++/6.3.0/bits/stl_algo.h:1965:25:   required from 'void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = boost::iterators::transform_iterator<std::__cxx11::basic_string<char> (*)(const foo&), __gnu_cxx::__normal_iterator<foo*, std::vector<foo> >, boost::iterators::use_default, boost::iterators::use_default>; _Compare = __gnu_cxx::__ops::_Iter_less_iter]'
/usr/local/include/c++/6.3.0/bits/stl_algo.h:4707:18:   required from 'void std::sort(_RAIter, _RAIter) [with _RAIter = boost::iterators::transform_iterator<std::__cxx11::basic_string<char> (*)(const foo&), __gnu_cxx::__normal_iterator<foo*, std::vector<foo> >, boost::iterators::use_default, boost::iterators::use_default>]'
/usr/local/include/boost/range/algorithm/sort.hpp:33:14:   required from 'RandomAccessRange& boost::range::sort(RandomAccessRange&) [with RandomAccessRange = boost::range_detail::transformed_range<std::__cxx11::basic_string<char> (*)(const foo&), std::vector<foo> >]'
main.cpp:27:57:   required from here
/usr/local/include/c++/6.3.0/bits/stl_algobase.h:148:11: error: no matching function for call to 'swap(boost::iterators::detail::iterator_facade_base<boost::iterators::transform_iterator<std::__cxx11::basic_string<char> (*)(const foo&), __gnu_cxx::__normal_iterator<foo*, std::vector<foo> >, boost::iterators::use_default, boost::iterators::use_default>, std::__cxx11::basic_string<char>, boost::iterators::random_access_traversal_tag, std::__cxx11::basic_string<char>, long int, false, false>::reference, boost::iterators::detail::iterator_facade_base<boost::iterators::transform_iterator<std::__cxx11::basic_string<char> (*)(const foo&), __gnu_cxx::__normal_iterator<foo*, std::vector<foo> >, boost::iterators::use_default, boost::iterators::use_default>, std::__cxx11::basic_string<char>, boost::iterators::random_access_traversal_tag, std::__cxx11::basic_string<char>, long int, false, false>::reference)'
       swap(*__a, *__b);
auto asString = boost::adaptors::transform(words, +[](foo& x) -> std::string& {return x.bar;});