Sometimes I like C++ just fine

And sometimes I want it to burn to a very nice crisp. That and everything it ever touched.

Just hit this ADL problem:
https://quuxplusone.github.io/blog/2018/06/17/std-size/

yay.


’Cause, you know, given the choice between two (or more) ADL matches, the compiler doesn’t think to choose from the explicitly active namespace...
In 20 years, I run into this problem exactly one time.
What’s your point?

The idea itself is only about 15 years old, and C++ didn't have it before 2011.

For your reference, I’ve been hacking for about 30 years, not quite half of that in C++.


ADL is a nice idea... until the Standard Library decides to use up all the common identifiers...


[edit]
It occurs to me that I am probably reading you wrong.

You’re probably saying, "Yeah, that’s an odd problem that likes to bite when you aren’t looking...”, and I’m all, “FLAME ON!”

Sorry. Flame off.

Last edited on
My point is, that I have only one problem with ADL since I programm in C/C++. So it can not be such a big problem ;)
I started reading the article you linked, and was like "wait how is this ADL, it's just because you injected size into the global namespace", but then I understood once I go this paragraph:
So the author tried replacing using namespace std; with a list of explicit using-directives. Unfortunately, this doesn’t help. We’re getting something we don’t expect out of namespace std, but it’s not because we using the namespace. It’s because of argument-dependent lookup (ADL). We made an unqualified call to size, where one of the arguments was a std::vector. This unqualified call, by ADL, naturally finds any function named size in any associated namespace of the argument type std::vector (and, incidentally, also considers namespace hr, although this has been widely regarded as a bad move.)

Yeah I can see that being really annoying for people that had the foresight to make those things templates before the standard did. Part of me is glad that the committee was able to make overall-positive, but breaking changes like that, but I can understand the pain.

I was watching a recent video where the presenter was talking about multi-step refactoring of very large codebases, and Argument-Dependent Lookup was one of the challenges.
https://www.youtube.com/watch?v=v_yzLe-wnfk
Last edited on
The whole point of namespaces is to control visibility of names, and when ADL decides that your very explicit namespace controls mean nothing, then, well, FLAME ON. LOL

ADL is great, but not recognizing that an object in a foreign namespace should not have the same precedence as an object in your explicit, current namespace — that is a design flaw.

IMO, the compiler should not be generating code that makes your code invalid.
I'm not sure what the original rationale for ADL was. Was was the problem it was trying to solve? It sure does seem like an anti-feature.

Would tricks like "using std::swap;" work without ADL? I would imagine so; the compiler should still be able to match the different overloads.
Last edited on
Ah, the fun of a committee mandating a continually evolving standard, implemented by committees.

whee :|

Old code shouldn't break, but it does rot.
I'm not sure what the original rationale for ADL was. Was was the problem it was trying to solve? It sure does seem like an anti-feature.

The hello world program relies on ADL. That is, it makes overloaded operators usable, and allows for library extension.

Would tricks like "using std::swap;" work without ADL?

The point of
using std::swap; swap(a, b);
is that it prefers to call the client's swap overload if it exists. Otherwise, it falls-back to the less-efficient and more general algorithm in the standard library.

That phrase only appears in generic code, so ADL is required in order to search the client's (maybe third-party) namespace for a suitable swap().

See Herb Sutter's A Modest Proposal: Fixing ADL:
https://wg21.link/p0934
Last edited on
Thanks, your link explains it perfectly.
Absent ADL, the choices to fix Example 1 would be: a) to qualify the << call (e.g., std::operator<<(std::cout, “Hello, world” );)
The main reason ADL doesn’t bite us harder most of the time is that there are:
  • specific use patterns — for example, overloading << for stream insertion
  • specific types used in an ADL namespace do not conflict with types in any other namespace
    — for example, std::setw()

The swap() example is both an example and a counter-example.

As an example, you can overload swap() to work specially over your specific (namespace qualified) types of objects.

As a counter-example, writing your own generic swap function will cause the compiler to flip out because it can’t decide which swap to use with a given generic argument. This is a common problem for C++ newbies in general, especially those trying to play with sort algorithms and the like, who are unfamiliar with the language and its weirdness.
https://www.google.com/search?q=c%2B%2B+swap+ambiguous
I am a self-taught (poorly) hobbyist programmer still finding my way through the C++ minefield.

This ADL issue is, IMO, made worse by the idiotic insistence instructors have with using namespace std; inserted in code taught to noobs.

Namespaces were added to the language standard for a reason. Fully qualify every use of the standard library. I do and it has become 2nd nature. My fingers go on auto-pilot.

Saving a few keystrokes makes my code "smell" bad to me now.

the huge irony of that was that namespace std was considered to be the right way for a while. Its taught because schools lag behind industry/professionals, in part, so they are still operating from back when this was 'good practice'.

Professors are often people that worked for a while (if you are lucky. Many never have done anything real), got their PHD, decided to teach and do research, and then stopped learning things like language trends and went off to focus on highbrow R&D problems. So they often teach their intro and intro+1 classes relying on what they knew when they retired from coding with few updates to that knowledge.
Last edited on
I don’t know of any time that “using namespace anything” was considered correct. It was introduced for the express purpose of untangling identifier pollution.

So... anyone teaching it as correct was, as you said, out of touch.
So... anyone teaching it as correct was, as you said, out of touch.

My first professor said it was bad practice and then proceeded to always use it and teach the whole class to use it.

My current professor didn't say it was bad practice and encourages it's use. He does this thing where he smirks when he thinks he's being clever and it just pisses me off. It really shouldn't, but it just does. Anyway, he encouraged it's use saying you write less code by omitting "std::", didn't feel like fighting him over every thing he says that is wrong or not recommended.
I'm not sure how true this is, but I remember reading somewhere that the initial reason for people using using namespace std was to transition from pre-standard C++ (including e.g. #include <iostream.h>, where there were no namespaces) to standard C++ without much code change.
Yes, that's one part of the feature rationale given in D&E (pg. 408).
BjarneStroustrup wrote:
Personally, I consider using-directives primarily as a transition tool.
Last edited on
A transition tool that is no longer needed, if only C++ was taught to modern standards. Too many instructors don't.

Older code is one thing. Writing new code to old, near-obsolete standards is not good.

@TwilightSpectre, I read something similar years ago myself. That is the main reason why I don't use it.

I really don't like in general using-declarations either, for example: using std::cout;

If I do have a using-declaration I restrict the scope as narrowly as possible. The way Boost is laid out makes me bend the "won't use ever" rule.

using also has a place as a type alias, if used sparingly. Rules can be bent when readability is enhanced.

zapshe wrote:
My first professor said it was bad practice and then proceeded to always use it and teach the whole class to use it.

Saint Bjarne says much the same, bad practice, and still uses it in his lectures and books on C++.

It wouldn't be so egregiously horrible, but he buries the using-directive in a header file he reuses again and again.

Too bad a perfectly good keyword (auto) is ignored by many instructors. C++11 usage makes replacement typing loooooong Standard Library/STL constructs easier to understand and read.

STL containers' iterators for example.
I never saw much reason for the namespace std, just the sites like this one were all recommending (or quietly using) it, books were using it, most code found online was using it, etc. No one said not-to and I don't even recall anyone saying bad practice. Came back from not using the language for a couple years and it was suddenly a big deal to everyone.

auto annoys me. I want to know what things are. I get the reasons, but they don't sit with me. Its a couple of small steps away from those awful typeless languages where one min a variable is a string, next its a double, then a boolean... etc. And it kills self documenting code when the user has to actually figure out what the compiler did there if there is a bug. I can't think of any good reason to use it, not sure what it does that you can't do by being explicit which I find much more readable. Ive gotten better at dealing with it, but I still don't like it and won't USE it myself.
Last edited on
I certainly prefer to use auto very judiciously. I'll use it in places where the actual type is obvious from context, and is long-winded to write out explicitly. For example, when declaring iterators:

1
2
3
4
5
std::vector<namespace1::namespace2::MyLongClassName> myVector;

// ...

auto myIter = myVector.begin();


it's obvious what type myIter should be, and the code is more readable than:

std::vector<namespace1::namespace2::MyLongClassName>::iterator myIter = myVector.begin();

Like you, I wouldn't advocate using it in places where it obscures information that's not obvious.
Last edited on
Topic archived. No new replies allowed.