Home > other >  How do I write a function signature such that it will take in a container or a range?
How do I write a function signature such that it will take in a container or a range?

Time:11-07

I was trying to make a function that takes in a container and implicitly have it convert to a boost::iterator_range as I thought that was it's purpose, but it seems that I'm missing something.

Here's an example of what I was thinking:

#include <boost/range/iterator_range.hpp>
#include <vector>

template<typename IT>
void fn_x(boost::iterator_range<IT>) {
}

void fn_y() {
    std::vector<int> a(64);
    fn_x(boost::make_iterator_range(a.begin(), a.end())); // Works
    fn_x(a);                                              // Doesn't
}

Demo

So how would I get fn_x to accept both a container and a range object, in the same function?

CodePudding user response:

#include <iterator>

template<typename IT>
void fn_x(boost::iterator_range<IT>) {
}

template<typename Range>
void fn_x(Range r) {
   fn_x(boost::make_iterator_range(std::begin(r), std::end(r));
}

I'm assuming that Range will come with a begin and end method

CodePudding user response:

This should be a comment, but I don't have enough reputation.

If you have access to c 20 you could try std::span.

Look at this monstrosity:

#include <algorithm>
#include <iostream>
#include <span>
#include <vector>

template <typename T>
struct ExistsFunctor {
  using UnderlyingT = typename T::value_type;
  bool operator()(std::span<UnderlyingT> span, UnderlyingT needle) {
    return std::find(span.begin(), span.end(), needle) != span.end();
  }
};

template <typename Container, typename T>
bool Exist(Container &container, T needle) {
  auto functor = ExistsFunctor<Container>();
  return functor(container, needle);
}

int main() {
  std::vector<int> arr{0, 1, 2, 3, 4};

  bool ok = Exist(arr, 3);

  if (ok) {
    std::cout << "ok" << '\n';
  } else {
    std::cout << "not ok" << '\n';
  }

  return 0;
}

  • Related