In the code below, as it stands, doesn't compile. But replace std::views::take(2)
with std::views::drop_while
and the code compile. I do understand that the take_view
and drop_while
view do different things, non the less, it shouldn't matter if I want to take some or drop some, I still should be able to copy those elems into the container.
#include <ranges>
#include <vector>
#include <iostream>
#include <unordered_map>
using namespace std;
int main()
{
//std::views::drop_while([](const int val){return val < 9;}) |
vector v{1,2,3,4,5,6,7,4,8,9};
std::ranges::take_view res = v | std::views::filter([](const int val){return val %2 == 0;}) | std::views::transform([](const int val){return val*3;})
| std::views::take(2);
decltype(v) filtered;
std::copy(res.begin(),res.end(),std::back_inserter(filtered));
for (const auto val : filtered)
{
std::cout << "val: " << val << '\n';
}
return 0;
}
Tried to look for explanation on the net. EDIT: Error:
main.cpp: In function ‘int main()’: main.cpp:23:14: error: no matching function for call to ‘copy(std::counted_iterator > >, main():: >, main():: >::_Iterator >, std::ranges::take_view > >, main():: >, main():: > >::_Sentinel, std::back_insert_iterator > >)’ 23 |
std::copy(res.begin(),res.end(),std::back_inserter(filtered)); | ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from /usr/include/c++/11/bits/char_traits.h:39, from /usr/include/c++/11/string:40, from /usr/include/c++/11/bits/locale_classes.h:40, from /usr/include/c++/11/bits/ios_base.h:41, from /usr/include/c++/11/streambuf:41, from /usr/include/c++/11/bits/streambuf_iterator.h:35, from /usr/include/c++/11/iterator:66, from /usr/include/c++/11/ranges:43, from main.cpp:9: /usr/include/c++/11/bits/stl_algobase.h:611:5: note: candidate: ‘template constexpr _OI std::copy(_II, _II, _OI)’ 611 | copy(_II __first, _II __last, _OI __result) | ^~~~ /usr/include/c++/11/bits/stl_algobase.h:611:5: note: template argument deduction/substitution failed: main.cpp:23:14: note: deduced conflicting types for parameter ‘_II’ (‘std::counted_iterator, main():: >, main():: >::_Iterator >’ and ‘std::ranges::take_view > >, main():: >, main():: > >::_Sentinel’) 23 | std::copy(res.begin(),res.end(),std::back_inserter(filtered)); | ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ In file included from /usr/include/c++/11/iterator:66, from /usr/include/c++/11/ranges:43, from main.cpp:9: /usr/include/c++/11/bits/streambuf_iterator.h:325:5: note: candidate: ‘template typename __gnu_cxx::__enable_if::__value, std::ostreambuf_iterator<_CharT> >::__type std::copy(std::istreambuf_iterator<_CharT>, std::istreambuf_iterator<_CharT>, std::ostreambuf_iterator<_CharT>)’
325 | copy(istreambuf_iterator<_CharT> __first, | ^~~~ /usr/include/c++/11/bits/streambuf_iterator.h:325:5: note: template argument deduction/substitution failed: main.cpp:23:14: note: ‘std::counted_iterator > >, main():: >, main():: >::_Iterator >’ is not derived from ‘std::istreambuf_iterator<_CharT>’ 23 |
std::copy(res.begin(),res.end(),std::back_inserter(filtered)); | ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The range
res
doesn't model Common Range, i.e. itsbegin()
andend()
have different types.The easy solution is to simply use the range version of the algorithm instead:
If you really need start and end (for a function such as
std::accumulate()
which is not yet rangeified), then we'll need to convert to a common range.Full program: