Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Receive any iterable container

Is there any way to receive any iterable container as a parameter?

I would like a function to be able to receive any container while being able to begin() and end() on it. Unless I am wrong, every container should have these functions (std::view does not?).

Specifically, is there a way to receive a Container as an argument?

C++20 and/or tempates are fine.

void do_stuff(any_iterable_collection<int> &coll) {
    for (auto it = coll.begin() ; it != coll.end() ; ++it) {
        // do stuff with *it
    }
}

std::list<int>   list;
std::vector<int> vector;
std::set<int>    set;

do_stuff(list);
do_stuff(vector);
do_stuff(set);
like image 264
Sinder Avatar asked Nov 03 '25 16:11

Sinder


2 Answers

A simplified c++20 concept based on your requirements:

#include <concepts>

template <typename C, typename T>
concept any_iterable_collection = 
    std::same_as<typename C::value_type, T> &&
    requires (C c) {
        { c.begin() } -> std::forward_iterator;
        { c.end() }   -> std::forward_iterator;
        { const_cast<const C&>(c).begin() } -> std::forward_iterator;
        { const_cast<const C&>(c).end() }   -> std::forward_iterator;
    };

Usage:

void do_stuff(const any_iterable_collection<int> auto& coll);

DEMO

like image 96
Piotr Skotnicki Avatar answered Nov 06 '25 09:11

Piotr Skotnicki


You can simply use the same way the standard perform this action:

template <typename Iterator>
void do_stuff(Iterator first, Iterator last) {
    for (auto it = first; it != last; it = std::next(it)) {
        // do stuff with *it
    }
}

int main() {

    std::vector<int> vec = {1, 5, 9};
    do_stuff(vec.begin(), vec.end());

    return EXIT_SUCCESS;
}

If you insist on the container:

template <template<typename> class Container>
void do_stuff(Container<int> &container) {
    for (auto it = std::begin(container); it != std::end(container); it = std::next(it)) {
        // do stuff with *it
        std::cout << *it << std::endl;
    }
}

Or for more generally container:

template <template<typename> class Container, typename CType>
void do_stuff(Container<CType> &container) {
    for (auto it = std::begin(container); it != std::end(container); it = std::next(it)) {
        // do stuff with *it
        std::cout << *it << std::endl;
    }
}
like image 23
CoralK Avatar answered Nov 06 '25 08:11

CoralK



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!