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?