0

I am building some snippets that should work with both the C++20 Ranges library and the range-v3 library and I noticed some differences in the implementation of the copy algorithm.

The following code using C++20 ranges library (from the Standard Library), compiles with GCC 11 (and prints 1 2 3 4 5).

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

int main()
{
    std::vector<int> arr {1, 2, 3, 4, 5};
    std::ranges::copy(arr, std::ostream_iterator<int>(std::cout, " "));   
}

Here is a link: https://wandbox.org/permlink/V13bdDoxSYjqDW3m

The same code, using the range-v3 library, fails to compile with VC++ 2019 16.5:

#include <iostream>
#include <vector>
#include "range/v3/algorithm/copy.hpp"

int main()
{
    std::vector<int> arr {1, 2, 3, 4, 5};
    ranges::copy(arr, std::ostream_iterator<int>(std::cout, " "));
}

With the following errors:

main.cpp(134,9): error C2672: 'operator __surrogate_func': no matching overloaded function found
main.cpp(134,59): error C7602: 'ranges::_copy::copy_fn::operator ()': the associated constraints are not satisfied
range-v3-master\include\range/v3/algorithm/copy.hpp(57): message : see declaration of 'ranges::_copy::copy_fn::operator ()'
main.cpp(134,59): error C2780: 'ranges::detail::in_out_result<I,O> ranges::_copy::copy_fn::operator ()(I,S,O) const': expects 3 arguments - 2 provided
range-v3-master\include\range/v3/algorithm/copy.hpp(45): message : see declaration of 'ranges::_copy::copy_fn::operator ()'

There is a unit test in the range-v3 library, which is very similar:

using namespace ranges;
std::ostringstream sout;
std::vector<int> copy_vec{1,1,1,1,1};
copy(copy_vec, ostream_iterator<>(sout, " "));
CHECK(sout.str() == "1 1 1 1 1 ");

If I try is with Compiler Explorer, it does not compile with any compiler (gcc, Clang, VC++). The gcc errors are:

note:   candidate expects 1 argument, 2 provided
note:   candidate expects 3 arguments, 2 provided
error: no match for call to '(const ranges::copy_fn) (std::vector<int>&, std::ostream_iterator<int>)'
required from here

These are basically the same errors that I see in VC++ for my snippet.

Here is a link: https://godbolt.org/z/pEfBb4

I would expect these two would work interchangeably. Why is it no so?

Marius Bancila
  • 16,053
  • 9
  • 49
  • 91

1 Answers1

1

Just to clarify for others looking at the question:

The unit test work because its ranges::ostream_iterator and not std::ostream_iterator that is used in that snippet.

The std::ostream_iterator does not work because it doesn't satisfy the range Iterator concept since it's not default constructible.

Marius Bancila
  • 16,053
  • 9
  • 49
  • 91