Suppose I have a class that extends a (STL) container and provides a customary begin member function:
#include <vector>
template <typename Cont>
struct Bar {
Cont c;
auto my_begin() { return begin(c); }
};
int main() {
Bar<std::vector<int>> b;
b.my_begin();
}
By ADL, I do not have to specify std:: before the begin() call. This is nice, as std::begin(v) will always try to call v.begin(), a user may want to use a custom container that has no .begin() interface, so if he defines his own free-function begin(v), Bar will use it.
However, it seems ADL will no longer work if I rename my_begin to begin as well, as if it was overshadowed. The compiler will just complain that it cannot find a matching call to begin in the class scope:
prog.cc: In instantiation of 'auto Bar<Cont>::begin() [with Cont = std::vector<int>]':
prog.cc:11:13: required from here
prog.cc:6:27: error: use of 'auto Bar<Cont>::begin() [with Cont = std::vector<int>]' before deduction of 'auto'
6 | auto begin() { return begin(c); }
| ^~~~~
prog.cc:6:32: error: no matching function for call to 'Bar<std::vector<int> >::begin(std::vector<int>&)'
6 | auto begin() { return begin(c); }
| ~~~~~^~~
prog.cc:6:10: note: candidate: 'auto Bar<Cont>::begin() [with Cont = std::vector<int>]'
6 | auto begin() { return begin(c); }
| ^~~~~
prog.cc:6:10: note: candidate expects 0 arguments, 1 provided
Of course, by writing std::begin, the code will run again, but this would just manifest the exclusion of ADL. What can I do, apart from renaming the member function?