Is it possible to have a C ++ template function that accepts any collection of type T?

I was wondering if there is a way to create a template function that references any collection of a particular type. eg:

class Bob
{
  public:
  int age;
  int height;
}

template<class T>
void functionWhichIteratesOverBobs(T &bobs)
{
    int totalAge = 0;
    for(auto &bob: bobs)
    {
         totalAge += bob.age;
    }
}

Basically, there is a way, in defining a template function, to require that T have a begin () and end () function that returns an iterator in T.

I saw the following question, but this will require a function starting and ending, i.e.

std::vector<Bob> bobs;
functionWhichIteratesOverBobs(bob.begin(), bob.end());

when I want:

std::vector<Bob> bobs;
functionWhichIteratesOverBobs(bobs);

A function that accepts an STL iterator through ANY container of elements of a certain type

+4
source share
3 answers

If you want the overload parameter to be unpolluted, use the SFINAE expression as follows:

template<class T>
void functionWhichIteratesOverBobs(T &bobs)
  -> decltype(std::begin(bobs), std::end(bobs), void()) {
    // [..Range based for over bobs..] 
}

, , , , , - , functionWhichIteratesOverBobs.

+1

++ Container - value_type , SFINAE , - , iterator_traits:

template<class T>
auto functionWhichIteratesOverBobs(T &bobs)
    -> std::enable_if_t<std::is_same_v<typename T::value_type, Bob>>
{
    // ...
}

, ; , , decltype(std::begin(bobs)) iterator_traits:

template<class T>
auto functionWhichIteratesOverBobs(T &bobs) -> std::enable_if_t<std::is_same_v<
    typename std::iterator_traits<decltype(std::begin(bobs))>::value_type, Bob>>
{
    // ...
}
0

. .

As Ed S. comment , just use the same function that you wrote in your question. If you bobshave not begin(), and end()the compiler will notify you by creating an error.
Demo .

0
source

All Articles