Home > Back-end >  Should the `begin` and `end` functions be overloaded inside the namespace `std`?
Should the `begin` and `end` functions be overloaded inside the namespace `std`?

Time:12-14

Recently I have been working on a code base which uses MFC and objects such as CArray<T, U>.

Some parts of new code which has been written make use of the STL and <algorithm> library.

For example

CArray<int int> carray;
carray // do stuff
std::vector<int> stlvector(begin(carray), end(carray));
stlvector.dostuff() // do stuff

I recently asked a question about creating iterators for a class such as CArray, which I do not have access to.

I now have some further questions about this. Here is my first question:

  • Should the begin and end functions be inside the std namespace?

I will ask the other questions separately and provide links to them shortly, replacing this line of text when those links are available.

CodePudding user response:

It can be useful to look at a non-trivial use of begin:

CArray<int> carray;
for (auto c : carray){
}

The begin is hidden in the range-for loop! Which begin(carray) is this? The name lookup rules here say that only argument-dependent lookup is done. There's no attempt to look at std::begin, since std is not at all related to CArray.

This makes sense. CArrayIterator begin(CArray) is a function that belongs to CArray, and therefore should be in the same namespace.

CodePudding user response:

To properly define the function, it should be defined in the same namespace as CArray. To properly use it generically, it should be used like, similar to the two-step swap idiom:

{
    using std::begin;
    begin(my_carray);
}

Alternative you might consider using some C 20 features that can wrap CArray, such as std::span and std::ranges::view_interface

  • Related