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