Of course, defining a helper function outside the class is a workaround (=as
is first defining a base class, as described in my original post).as
The point I would like to make, however, is another one.
There are workarounds, yet they get the more tedious the more often the problem arises, namely in templated code. (To begin with: templates live mostly in headers, so the helper functions must live in headers as well,
and break encapsulation, pollute my namespace or are simply inconvenient =
they have to be templates themselves).n
It seems consensus (more or less) now that non-member functions defined i=
the same namespace as a class are part of the interface of that class, BECAUSE they will usually be found by ADL.e
Now the rule that, within a member function of some class, say B, member functions of B take absolute precendence when a name is looked up, has th=
unwanted effect that some part of the interface of another, completely unrelated class A, namely the nonmember functions that belong to the interface of A, may become unusable from within B.a
Why can I write
using namespace std;
auto i = begin (vec);
everywhere in my code, yet not within a class that has a member function named begin ()?
I tempted to think this should be considered a design mistake.
One could think of several approaches to solve that problem:
1.) Introduce a clause like
using explicit this;
which would locally force explicitly using this-> when you want to access=
member. Then I would write
using namespace std;
using explicit this;
auto i = begin (vec); // ADL
auto j = this->begin (); // member
2.) Introduce a special qualifier (like, e.g., .::) to indicate that the following name does *not* refer to a member function. Then I could write
using namespace std;
auto i = .::begin (vec); // ADL
auto j = begin (); // member
...
Why can I write
using namespace std;
auto i = begin (vec);
everywhere in my code, yet not within a class that has a member function named begin ()?
...
Doesn't the existing :: qualifier do this already:
auto i == ::begin(vec); // ADL
Or did I miss some unfortunate interaction with the way named namespaces
were formally added to the language?
Enjoy
Jakob
--
Jakob Bohm, CIO, Partner, WiseMo A/S. https://www.wisemo.com
Transformervej 29, 2860 S=C3=B8borg, Denmark. Direct +45 31 13 16 10
This public discussion message is non-binding and may contain errors.
WiseMo - Remote Service Management for PCs, Phones and Embedded
function of the same name as the function you would like to be called.
...n
Why can I write
using namespace std;
auto i = begin (vec);
everywhere in my code, yet not within a class that has a member functio=
dNo, it doesn't.named begin ()?
...
Doesn't the existing :: qualifier do this already:
auto i == ::begin(vec); // ADL
Or did I miss some unfortunate interaction with the way named namespaces
were formally added to the language?
::begin is considered as a qualified id, and ADL is not done for qualifie=
ids ([basic.lookup.argdep], paragraph 1). ::begin will always only refer =to
the global namespace ([basic.lookup.qual], paragraph 4).
On 27/07/15 18:22, Johannes Gerd Becker wrote:
Currently, you cannot rely on ADL within a class defining a member
function of the same name as the function you would like to be called.
I must admit that my C++ is getting a bit rusty, but this "problem" was well-known a decade ago, typically manifesting with std::swap and member functions of the name. The solution then was equally well known, and continues to work in C++11/14:
using std::begin;
auto i = begin(c);
Richard
--
[ comp.std.c++ is moderated. To submit articles, try posting with your ]
[ newsreader. If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 286 |
Nodes: | 16 (2 / 14) |
Uptime: | 82:50:44 |
Calls: | 6,495 |
Calls today: | 6 |
Files: | 12,096 |
Messages: | 5,276,825 |