I really like the new concept of free begin
end
to write more generic algorithms and data structures. Currently it sometimes happens to me that I have to differentiate between calls begin(range)
and begin(*range)
when a type holds a reference to a collection as pointer. I thought about if it is a good idea to always provide an overload of begin/end for pointers for my own collection types.
struct Container {
int values[3];
};
const int* begin(const Container& c);
const int* end(const Container& c);
const int* begin(const Container* c);
const int* end(const Container* c);
template<typename Range>
int Sum(const Range& range)
{
return std::accumulate(begin(range), end(range), 0);
}
int main(void)
{
Container c = {1, 2, 3};
std::cout << Sum(c);
std::cout << Sum(&c);
}
If this was a good idea why not provide a template for this:
template<typename Range>
auto begin(const Range* r) -> decltype(begin(*r)){
using std::begin;
return begin(*r);
}
template<typename Range>
auto end(const Range* r) -> decltype(end(*r)) { /* ... */ }
int main(void)
{
Container c = {1, 2, 3};
std::vector<int> v = {1, 2, 3}
std::cout << Sum(c);
std::cout << Sum(&c);
std::cout << Sum(v);
std::cout << Sum(&v);
}
If this was a good idea why doesn't the standard library define it?
My question is: Is there anything wrong with a template<typename R>
auto begin(const R* r)
template? Are there any cases where this fails for some reason?
If you do this you can no longer use std::begin()
and std::end()
overloaded for arrays:
Container c[2] = { };
std::accumulate(begin(c), end(c), 0);
This shouldn't compile, because you can't add c[i]
to 0
, but it does because the begin(Container*)
overloads are selected instead of the generic std::begin(T (&)[N])
one.
For another example:
Container c[2] = { };
auto dist = std::distance(begin(c), end(c));
this should set dist=2
, because the array has two elements, but instead you get dist=3
because end(*c) - begin(*c)
equals 3.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With