Quite frequently in C++11 I need to define a function that takes a container as a parameter.
For example lets define a function addup (yes just a simple version of std::accumulate):
template <class I>
int addup (I first, I last)
{
int x = 0;
while ( first != last )
x += *first++;
return x;
}
This takes an iterator range, which is flexible and the standard library idiom.
However suppose I have a function:
vector<T> f();
I have to do this:
auto v = f();
int x = addup(v.begin(), v.end());
I would rather just do this:
int x = addup(f());
Just like I can do this:
for (auto t : f())
...
In the spirit of range-based for I would like something like this:
template<class C>
int addup(C&& container)
{
addup(beginexpr(container), endexpr(container)); // ???
}
In the standard it says in 6.5.4 (paraphrasing):
(A) if
containeris an array type,beginexprandendexprarecontainerandcontainer+bound, respectively, whereboundis the array bound.(B) if
containeris a class type, the unqualified-idsbeginandendare looked up in the scope of classcontaineras if by class member access lookup (3.4.5), and if either (or both) finds at least one declaration,beginexprandendexprare container.begin() and container.end(), respectively;(C) otherwise,
beginexprandendexprarebegin(container)andend(container), respectively, where begin and end are looked up with argument-dependent lookup (3.4.2).
Is it possible to define a set of overloads or specializations of addup such that it will handle the four cases, and not conflict with other overloads? That is firstly a regular iterator pair function, and then each of A, B and C above. How?
(If this is possible than why doesn't the standard library offer such overloads?)
Also, what if the function takes extra parameters beyond the container? Can we modify the overloads in such a way that an optional extra parameter x (one with a default value) added to all of them will not make the following two calls ambiguous:
addup(v.begin(), v.end());
addup(v, x);
That is can we statically assert (using "SFINAE" or similar) that the template parameter has to be an iterator, an array, a container class, etc - and have this information used for overload disambiguation?