I would like a C++ constructor/method to be able to take any container as argument. In C# this would be easy by using IEnumerable, is there an equivalent in C++/STL ?
Anthony
I would like a C++ constructor/method to be able to take any container as argument. In C# this would be easy by using IEnumerable, is there an equivalent in C++/STL ?
Anthony
The C++ way to do this is with iterators. Just like all the <algorithm>
functions that take (it begin, it end, )
as first two parameters.
template <class IT>
T foo(IT first, IT last)
{
return std::accumulate(first, last, T());
}
If you really want to go passing the container itself to the function, you have to use 'template template' parameters. This is due to the fact that C++ standard library containers are not only templated with the type of the contained type, but also with an allocator type, that have a default value and is therefore implicit and not known.
#include <vector>
#include <list>
#include <numeric>
#include <iostream>
template <class T, class A, template <class T, class A> class CONT>
T foo(CONT<T, A> &cont)
{
return std::accumulate(cont.begin(), cont.end(), T());
}
int main()
{
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
std::list<int> l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
std::cout << foo(v) << " " << foo(l) << "\n";
return 0;
}
Depends what you want to do with the container. One thought: just pass an iterator if you want to access what is stored in the container.
A good question, +1. What a pity, its two years old... I post an answer anyway: You're stuck with the "C++ way" if you only want to expose an interface of your library. My way to do that is this:
template<class TValue>
class IEnumerator {
public:
virtual bool MoveNext() = 0;
vírtual TValue Current() = 0;
virtual void Reset() = 0;
};
template<class TValue>
class IEnumerable {
public:
virtual std::unique_ptr< IEnumerator<TValue> > GetEnumerator() const = 0;
};
This way, you can write APIs of the following kind:
void MyAPI(const IEnumerable<IMyLibAPIObject>& pSequence);
Of course, I provide different implementations like StlEnumerator
or StlEnumerable
, or EnumeratorAdaptor<T, U>
to get covariance as in C#...
Cheers,
Paul
Edit: So far I ended up with a type erasing 'AnyEnumerator' and 'AnyEnumerable'. Also, I am how aware of the various 'any_iterator' implementations...