ericniebler / range-v3

Range library for C++14/17/20, basis for C++20's std::ranges
Other
4.11k stars 440 forks source link

Cannot construct range from shared_ptr to unordered_map #1605

Closed alexsn closed 2 months ago

alexsn commented 3 years ago

I'm trying to create a view which binds to a shared_ptr (which should be possible following https://github.com/ericniebler/range-v3/pull/557#issue-102835478) on construction as follows:

#include <iostream>
#include <memory>
#include <range/v3/all.hpp>
#include <range/v3/experimental/view/shared.hpp>
#include <unordered_map>

int main() {
  auto configs = std::make_shared<std::unordered_map<int, std::string>>();
  configs->insert({1, "foo"});
  configs->insert({2, "bar"});
  configs->insert({3, "baz"});

  auto &&rng =
      configs | ranges::experimental::views::shared | ranges::views::keys;

  for (auto &&[k, v] : rng) {
    std::cout << k << ": " << v << '\n';
  }

  return 0;
}

However this fails to compile with the following output:

main.cpp:14:15: error: invalid operands to binary expression ('std::__1::shared_ptr<std::__1::unordered_map<int, std::__1::basic_string<char>,
      std::__1::hash<int>, std::__1::equal_to<int>, std::__1::allocator<std::__1::pair<const int, std::__1::basic_string<char> > > > >' and 'const
      shared_closure<ranges::experimental::views::shared_fn>')
      configs | ranges::experimental::views::shared | ranges::views::keys;
      ~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode_12.3.0_fb.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/cstddef:67:17: note: candidate
      function not viable: no known conversion from 'std::__1::shared_ptr<std::__1::unordered_map<int, std::__1::basic_string<char>,
      std::__1::hash<int>, std::__1::equal_to<int>, std::__1::allocator<std::__1::pair<const int, std::__1::basic_string<char> > > > >' to
      'std::byte' for 1st argument
constexpr byte  operator| (byte  __lhs, byte __rhs) noexcept
                ^
/Applications/Xcode_12.3.0_fb.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/bitset:1071:1: note: candidate
      template ignored: could not match 'bitset' against 'shared_ptr'
operator|(const bitset<_Size>& __x, const bitset<_Size>& __y) _NOEXCEPT
^
/usr/local/include/range/v3/experimental/view/shared.hpp:80:35: note: candidate template ignored: requirement
      'range<std::__1::shared_ptr<std::__1::unordered_map<int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>
      >, std::__1::hash<int>, std::__1::equal_to<int>, std::__1::allocator<std::__1::pair<const int, std::__1::basic_string<char,
      std::__1::char_traits<char>, std::__1::allocator<char> > > > > > &>' was not satisfied [with Rng =
      std::__1::shared_ptr<std::__1::unordered_map<int, std::__1::basic_string<char>, std::__1::hash<int>, std::__1::equal_to<int>,
      std::__1::allocator<std::__1::pair<const int, std::__1::basic_string<char> > > > > &, SharedFn = ranges::experimental::views::shared_fn,
      CPP_true = true]
            friend constexpr auto operator|(Rng && rng, shared_closure<SharedFn> vw)
                                  ^
/usr/local/include/range/v3/experimental/view/shared.hpp:86:35: note: candidate template ignored: could not match 'shared_closure' against
      'shared_ptr'
            friend constexpr auto operator|(shared_closure<SharedFn> sh, Pipeable pipe)
                                  ^
1 error generated.

Is this possible without writing your own views?