Closed GoogleCodeExporter closed 9 years ago
Can you tell me where I can find the suggestion to call begin/end unqualified?
I'm not sure it is a good one.
If a user decides to use unqualified std::begin/std::end, one:
a. loses support for iterating over arrays (ADL does not work on built-in
arrays)
b. loses support for iterating over custom library types that do not explicitly
implement begin/end free functions
On the other hand, std::begin(v) uses v.begin() without the need to change the
type - what value does ADL bring here?
Original comment by arseny.k...@gmail.com
on 6 Mar 2013 at 4:14
I should add that you only need to use all when calling begin/end with a type
that has been passed through a template. If you don't use ADL user-supplied
types will not work if their begin/end implementation doesn't simply call
a.begin/end. Users are not allowed to overload begin/end so a non-adl call
could not find their versions.
Your first point is wrong: an unqualified call will still work for arrays due
to the using directive.
The second point is wrong for the same reason, if there is no begin/end for the
type, std::begin takes care of it.
This is the same as for generically calling std::swap.
Original comment by bootsare...@gmail.com
on 6 Mar 2013 at 4:29
I'm confused. What using directive are you speaking of?
Once again, suppose you have a generic function:
template <typename T> void iter(T& container)
{
auto it = begin(container);
...
}
Why would you, as a author of the iter function, use begin as opposed to
std::begin? I do not see any benefits, and I believe the drawbacks a./b. from
the comment #1 apply.
std::swap is very different in my opinion. The difference is that by using a
qualified call to std::swap you are always using the generic (inefficient,
non-customizable) version of swapping. You do not have this problem when you're
using std::begin - it just delegates to v.begin() except for a few special
cases, like arrays.
Original comment by arseny.k...@gmail.com
on 6 Mar 2013 at 6:00
I'd use an unqualified call with a using directive because I want the same
customizable behavior for begin/end that I have for swap. This can be very
useful when adapting types to libraries where I cannot modify the original type
or modification would break things. Or for cases where there is no begin/end
member but something more specified, e.g. begin_points, and you want
compatability with range for loops.
Original comment by bootsare...@gmail.com
on 7 Mar 2013 at 4:59
I've asked the question on StackOverflow and, while opinions diverged, the
consensus is that the generic code should either use a qualified call to
std::begin or use an unqualified call and do using std::begin so that ADL can
work if necessary but fall back to the std:: implementation. This means that
you can use ADL to provide iteration for containers that are not compatible
with the standard interface, but containers that already have member begin/end
functions do not have to do anything else.
Please refer to
http://stackoverflow.com/questions/17562943/should-custom-containers-have-free-b
egin-end-functions
Original comment by arseny.k...@gmail.com
on 10 Jul 2013 at 2:52
Original issue reported on code.google.com by
bootsare...@gmail.com
on 7 Sep 2012 at 10:00