我想根據foo
的成員獲得vector<foo>
中的獨特元素。我使用boost::adaptors::transform
來選擇成員,然後排序,然後使用boost::adaptors::unique
。我無法讓排序步驟起作用。撇開unique
現在呼籲,我已經嘗試Coliru下面的代碼。如何提升:: range :: sort()boost :: transformed_range?
#include <iostream>
#include <string>
#include <vector>
#include <boost/range/adaptor/transformed.hpp>
#include <boost/range/algorithm/sort.hpp>
struct foo
{
foo(std::string a) : bar(a) {}
std::string bar;
bool operator<(const foo& rhs) const {return bar < rhs.bar;}
};
int main()
{
std::vector<foo> words = { foo("z"), foo("d"), foo("b"), foo("c") };
#if 1
{
auto asString = boost::adaptors::transform(words, +[](const foo& x) {return x.bar;});
auto sortedStrings = boost::range::sort(asString);
for (const auto& el : sortedStrings)
std::cout << el << std::endl;
}
#else
{
auto asString = boost::adaptors::transform(words, +[](const foo& x) {return x.bar;});
std::sort(asString.begin().base(), asString.end().base());
for (const auto& el : asString)
std::cout << el << std::endl;
}
{
auto sortedStrings = boost::range::sort(words);
for (const auto& el : sortedStrings)
std::cout << el.bar << std::endl;
}
#endif
return 0;
}
的#if
部分不起作用:
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);
儘管std::sort
與基迭代器類型的#else
節不工作。我不明白爲什麼。在我的真實使用案例中,我也在使用boost::adaptors::indirect
和boost::adaptors::filter
(並且我希望在進行排序前進行過濾,或者至少嘗試這樣做,看看它是如何執行的),所以這就是爲什麼我不是簡單的在執行轉換之前用lambda謂詞對words
進行排序。
'boost :: swap(* asString.begin(),* asString.begin());'失敗。 – Jarod42
你不能。排序需要隨機訪問。 – sehe
@sehe transform()文檔聲明它返回的是相同的範圍類型,因此它應該是隨機訪問,對吧? –