Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
283 views
in Technique[技术] by (71.8m points)

c++ - Why is the pipe operator not working when I use ranges in C++20?

I am currently working through examples from the book Expert C++.

In chapter 7, they offer the following code for mapping a function to a matrix:

#include <vector>
#include <ranges>
#include <iostream>

using IntMatrix = std::vector<std::vector<int>>;

int count_evens(const std::vector<int>& number_line) {
    return std::count_if(number_line.begin(),
                         number_line.end(), [](int num){return num % 2 == 0;});
}

std::vector<int> count_all_evens(const IntMatrix& numbers)
{
    return numbers | std::ranges::views::transform(count_evens); // ERROR APPEARS HERE AT |
}

int main()
{
    IntMatrix m{{1, 2, 3}, {4, 5, 6}};
    for (auto item : count_all_evens(m)) {
        std::cout << item << " ";
    }
    std::cout << std::endl;
    return 0;
}

I am getting an error on line 14 that says:

could not convert 'std::ranges::views::__adaptor::operator|<const std::vector<std::vector<int> >&>((* & numbers), std::ranges::views::transform.std::ranges::views::__adaptor::_RangeAdaptor<std::ranges::views::<lambda(_Range&&, _Fp&&)> >::operator()<int (&)(const std::vector<int, std::allocator<int> >&)>(count_evens))' from 'std::ranges::transform_view<std::ranges::ref_view<const std::vector<std::vector<int> > >, int (*)(const std::vector<int>&)>' to 'std::vector<int>'

Does anyone else have this issue? I am using the g++10 compiler.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
std::vector<int> count_all_evens(const IntMatrix& numbers)
{
  auto view = numbers | std::ranges::views::transform(count_evens);
  return {view.begin(), view.end()};
}

there is a proposal to make this suck less.

std::vector<int> count_all_evens(const IntMatrix& numbers)
{
  auto view = numbers | std::ranges::views::transform(count_evens);
  return std::ranges::to<std::vector<int>>(view);
}

You can also get fancy

template<class Range>
struct to_container {
  Range&& r;
  template<class Container>
  operator Container()&&{ return {r.begin(), r.end()}; }
};
template<class Range>
to_container(Range&&)->to_container<Range>;

std::vector<int> count_all_evens(const IntMatrix& numbers)
{
  return to_container{ numbers | std::ranges::views::transform(count_evens) };
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...