PacktPublishing / Expert-CPP

Expert C++, published by Packt
85 stars 60 forks source link

count_evens_functional.cpp resulting in compile time error because the resulting expression of the pipe is not convertible to vector<int>. #3

Closed smartin1296 closed 3 years ago

smartin1296 commented 3 years ago

I am unable to compile the code becase of an error in line 14. The resulting expression of that pipe is not convertible to vector.

'return numbers | std::ranges::views::transform(count_evens);'

The error says:

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

I am using the g++ compiler as suggested at the beginning of the chapter.

smartin1296 commented 3 years ago

I solved this by adding a view to the count_all_evens function and returning the view iterables.

#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) {
    auto view = numbers | std::ranges::views::transform(count_evens);
    return {view.begin(), view.end()};
}

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;
}