New to C++

Ö

Öö Tiib

And you can tell him the issue in one minute.

Geniuses (who solve any problem under minute) can. For them that 'using
namespace std' is certainly harmless. I am not one, sorry. I have never
even met one.
I don't know if a "C++ programmer" who has to sit and stare more than five
minutes to find out a namespace clash can produce many important things in
that time.

Lucky you. Congrats. For me ... world is totally different. I do not claim
to write oh so many important things. C++ code is never simple and short
like in textbooks for me. It takes some time to see what is going on
in it.

Example from my sad practice: some non-std::ref (a member function accepting
same argument) has been assumed by compiler into that std::bind. The error
messages are strange and fail to tell anything about 'ref'. If to qualify that
'ref' then the problems disappear. Also, problems disappear if to rename that member function. That however is not what mine (non-genius) C++ programmer
noob tries. He thinks that he misunderstood something about how std::bind or
std::ref works. Googles and reads. Tries different things. Finally, when he
asks for help frustrated the code is actually wrong too. Then I have to
understand what he wanted to achieve, what he has written and what there
actually should be.

If he had never used 'using namespace std' then he could had written it
himself under 5 minutes yes. So for him and me that 'using namespace std'
is harmful, for you it apparently is not.

But in programming, a string is so universal and has a well defined
meaning, so you better don't use your exotic string unqualified.

Depends. If it is application that works with UTF-8 texts then std::string
is used a lot. If it is a module that has to cooperate tightly with some
MS API or with Java code or with C# code then the texts are more efficient
to handle as UTF-16. As result ... std::string has next to no usage there,
despite being so universal and what else you said.
Use "yourdomain::string" for your exotic string class and just "string" for
std::string. And for the case that you are actually inside yourdomain
namespace, you can still use std::string qualified or if you don't use
std::string at all, just don't #include <string>.

Can't ... if std::wstring is still used. Why ... now we have IMHO so lot of
complications here just to allow that 'using namespace std'?
I don't understand why now you are arguing with such convoluted names like
cord_used_to_tie. I never suggested not using namespaces at all.

That was maybe somewhat silly example on case of string. In general it is
similar to what people often do when they get lot of clashes. Naming thingslike 'electoral_list' or 'mailing_list' instead of 'list' makes sense but
it is easy to go too far there.
Why #including <thread> in the first place?

Any standard library header #included has right to #include on its order
any other standard library headers that the implementation sees fit.

Typically it happens so that maintenance adds #include <something> to some
header. <something> includes <other_thing> that clashes. Maintainer gets
strange error messages (not related to <something>) in somewhat related
code. So there 'using namespace std' was the bear trap that waited for that
maintainer and caused him some nuisance he was not prepared for. Yes,
for the under-a-minute fixers of yours it is maybe non-issue.
The whole point of namespaces actually is, that you don't _have_ to use it
unless you have a name clash. And if you have one, you can fix it on the
client side.

But do not you feel that something has been 'broken' if it needs 'fixing'?

Usually I work in scope of some member function of some class in some
namespace. So there are 3 nested name scopes already. I do not need to
qualify names from these scopes. If the class has base class then names
from it too.

External names I either import or alias or use fully qualified. Such importing
and aliasing code is clear and documents my intentions. Nothing ever clashes.

'using namespace' on the other hand is lazy shortcut that imports whole
namespace, documents nothing and unless it causes clashes immediately it
works like time bomb that one needs to fix in the future.
Otherwise they would not be a real improvement over std_string and your
cord_used_to_tie.


Then they used qualified names...

Yes, indeed, that step I implied. They use that first, to fix clashes.
Still ... they get feed up with fixing clashes and ...
Huh, why that? Are they C programmers?

Because namespaces are broken for coders who use 'using namespace' a lot.
You mean like: yourdomain::yoursubdomain::yoursubdubdomain::list?

No. That is the other edge way how to go too far with namespaces by
by splitting it into small namespaces with long names. C++ has
fortunately a cure to it:

namespace region = thatdomain::thatsubdomain::thatsubdubdomain;
 
Ö

Öö Tiib

A very good example, that should be framed on the wall.

Are you being sarcastic? It is good example.
Demonstrating the main misconception about code reading (and
consequently writing).

So, to answer your first question, the first line shout bell:

"that is a predicate function taking three items, not modifying them,
and returning true if all are equal". The second should bell the same +
"and it has noise".

That first one maybe is implemented exactly like you describe, who knows.

That second one I know. It certainly requires that the a, b and c are
iterators. There are two iterator ranges compared for equality.
The ranges are [a,b) and [c,c') where c' is as far from c as b is from a.
The exact signature of the function, the place of its implementation,
and the other stuff is completely irrelevant. (If you actually need to
know it's an indication of systemic trouble.)

What? You must always know what the tools that you use do. There are no
universal rules in existence what every function or member function or
functor that happens to have name 'equal' and happens to accept 3
parameters should do.
OTOH if you're in the marginal situation to need the implementation, it
is just a click or keystroke away, unless you use some stone-age tools.

Who needs to read implementation of std::equal? It is quite well-documented.
No need to read its implementation to find out what it does.
 
T

Tobias Müller

Öö Tiib said:
Geniuses (who solve any problem under minute) can. For them that 'using
namespace std' is certainly harmless. I am not one, sorry. I have never
even met one.

Usually, the error message is something like: the use of identifier 'blah'
is ambiguous, possible candidates are...
This may include some lengthy templated types, but nothing hard to
understand if you read it carefully.
Lucky you. Congrats. For me ... world is totally different. I do not claim
to write oh so many important things. C++ code is never simple and short
like in textbooks for me. It takes some time to see what is going on
in it.

Sure, but I would assume that error messages from template clashes are not
the most difficult to understand. There may be exceptions, but I've never
met one.
Example from my sad practice: some non-std::ref (a member function accepting
same argument) has been assumed by compiler into that std::bind.

I'm sorry but I just don't understand that sentence, so I cannot comment on
that issue.
The error
messages are strange and fail to tell anything about 'ref'. If to qualify that
'ref' then the problems disappear. Also, problems disappear if to rename
that member function. That however is not what mine (non-genius) C++ programmer
noob tries. He thinks that he misunderstood something about how std::bind or
std::ref works. Googles and reads. Tries different things. Finally, when he
asks for help frustrated the code is actually wrong too. Then I have to
understand what he wanted to achieve, what he has written and what there
actually should be.

If he had never used 'using namespace std' then he could had written it
himself under 5 minutes yes. So for him and me that 'using namespace std'
is harmful, for you it apparently is not.

Error messages in C++ compilers are not always helpful or straight forward.
But that's true for almost all nontrivial and sometimes even for trivial
errors, not only the one that you describe.
Over time you'll get a feeling what the message really means.

Anyway, I'm not going to abandon a language feature only because it may
lead to cryptical error messages in some rare cases. I would probably have
to forbid most features of C++.
Depends. If it is application that works with UTF-8 texts then std::string
is used a lot. If it is a module that has to cooperate tightly with some
MS API or with Java code or with C# code then the texts are more efficient
to handle as UTF-16. As result ... std::string has next to no usage there,
despite being so universal and what else you said.

That's not my point. I meant that string as a sequence of characters (in
whatever encoding and chartype) is such a universal concept in programming,
that you better don't use your exotic string class (representing a cord
used to tie) unqualified if you don't want to deliberately provoke
confusion.
The same is IMO true for most identifiers in namespace std.
Can't ... if std::wstring is still used.

That last sentence of mine is the least important of the cited paragraph.
It is just a suggestion to omit collisions, not a necessity.
Why ... now we have IMHO so lot of
complications here just to allow that 'using namespace std'?

What complications?
That was maybe somewhat silly example on case of string. In general it is
similar to what people often do when they get lot of clashes. Naming
things like 'electoral_list' or 'mailing_list' instead of 'list' makes sense but
it is easy to go too far there.

If your list can only contain email adresses, then mailing_list is a very
reasonable name. Much clearer than only list. And if not, then I'd still
prefer a name that tells me the difference to std::list, because if there
is none why not just use std::list.
Like std::map vs. std::unordered_map. Or would you prefer
std::unordered_containers::map?
Any standard library header #included has right to #include on its order
any other standard library headers that the implementation sees fit.

True but usually they make only reasonable #inclusions. And I wouldn't call
Typically it happens so that maintenance adds #include <something> to some
header. <something> includes <other_thing> that clashes. Maintainer gets
strange error messages (not related to <something>) in somewhat related
code. So there 'using namespace std' was the bear trap that waited for that
maintainer and caused him some nuisance he was not prepared for. Yes,
for the under-a-minute fixers of yours it is maybe non-issue.


But do not you feel that something has been 'broken' if it needs 'fixing'?

What something? Such an error does not appear out of nothing. You have to
make a change to the code or the environment. And if you did not anticipate
all consequences of that change, then your change is broken, not the
existing code nor the C++ language.
Usually I work in scope of some member function of some class in some
namespace. So there are 3 nested name scopes already. I do not need to
qualify names from these scopes. If the class has base class then names
from it too.

But here we are mainly talking about namespace std.
External names I either import or alias or use fully qualified. Such importing
and aliasing code is clear and documents my intentions. Nothing ever clashes.

'using namespace' on the other hand is lazy shortcut that imports whole
namespace, documents nothing and unless it causes clashes immediately it
works like time bomb that one needs to fix in the future.

For arbitrary external code that's of course the best you can do. For the
standard library I don't agree.
Yes, indeed, that step I implied. They use that first, to fix clashes.
Still ... they get feed up with fixing clashes and ...

I don't believe that name clashes with std are so frequent.
Because namespaces are broken for coders who use 'using namespace' a lot.

I was only talking about std.
No. That is the other edge way how to go too far with namespaces by
by splitting it into small namespaces with long names. C++ has
fortunately a cure to it:

namespace region = thatdomain::thatsubdomain::thatsubdubdomain;

And hope that 'region' does not clash with a real namespace im the future.

But you're right of course. I didn't want to deny the usability of
namespaces at all.

Tobi
 
J

Jorgen Grahn

Functions are a different breed, as they form overload sets.


Can't tell without context. The first rule of overload sets is that all
members have the same semantics. I mean SAME :).

That's a rule I was unaware of. I happily break it, all the time.
A freestanding find()? I'd expect it to need two pieces of info: where
and what. And return an lvalue or some pointer/index/...

I was unclear (I meant a plain function) and I forgot the key. It
should have been something like:

Book find(const Library&, int id);

/Jorgen
 
Ö

Öö Tiib

Usually, the error message is something like: the use of identifier 'blah'
is ambiguous, possible candidates are...
This may include some lengthy templated types, but nothing hard to
understand if you read it carefully.

When it just makes overload resolution to fail then that is easy. Then there are
list of ambiguous functions. Function names are only subset of names
in C++ standard library.
Over time you'll get a feeling what the message really means.

Sure. Things change. Language evolves, compilers and tools get better. Then
I will relearn. Right now I feel that 'using namespace' does wrong thing that I
don't need.
Anyway, I'm not going to abandon a language feature only because it may
lead to cryptical error messages in some rare cases. I would probably have
to forbid most features of C++.

Most people abandon lot of C++ features sooner or later. For example
there are very few who use raw pointer and new[] and delete[] for dynamic
array, majority use std::vector instead. Very rare ever consider overloading
operator,(), operator&&() or operator||(). Very rare use throw in destructor,
very rare call virtual functions from constructor or from destructor. etc.
These are all features that compile to valid code in C++ language.
However ... the behavior may be confusing and error prone so ... lot of
people have abandoned those.

People who avoid that 'using namespace' do it for similar reasons. It makes
code fragile.
That's not my point. I meant that string as a sequence of characters (in
whatever encoding and chartype) is such a universal concept in programming,
that you better don't use your exotic string class (representing a cord
used to tie) unqualified if you don't want to deliberately provoke
confusion.

The same is IMO true for most identifiers in namespace std.

There we differ. There are too lot of convenient short names in namespace std
to demand that these names are sacred and should never be used otherwise.
Why authors of C++ did put them into that namespace? I think because they
saw as well that these names can mean entirely other things in some other
context.
That last sentence of mine is the least important of the cited paragraph.
It is just a suggestion to omit collisions, not a necessity.

That last sentence was the only one that did matter to me. Most uses of some
name defined are in the scope where it was defined, IOW within the
namespace of that name. Using it qualified within the same namespace is
strange.
What complications?

That I may never use any name from std namespace for something unqualified
Like std::map vs. std::unordered_map. Or would you prefer
std::unordered_containers::map?

No, std::map and std::unordered_map are similar containers. I mean things with
clear domain-specific meaning like 'building::floor::map'. That is not like
std::map at all. It prevents unqualified usage of std::map and maybe std::floor
by hiding those. The author of such unqualified usage may be some other person.
So the author of that map may need to use 'building::building_floor::floor_map'
or something like that to avoid breaking (or maintaining) other person's code.
In short ... stammer, just to legalize saving 5 characters 'std::' in few places.
What something? Such an error does not appear out of nothing. You have to
make a change to the code or the environment. And if you did not anticipate
all consequences of that change, then your change is broken, not the
existing code nor the C++ language.

Hmm. There are two things that can cause something to break. Someone did
apply too lot of power or that the something was fragile and easy to break.

Someone wrote code that stops compiling because I started include <thread> in
my class header that they happen to include. Did it break because of their usage
of 'using namespace std' did make their code fragile or did it break because of
my oh so "evil" change?
I don't believe that name clashes with std are so frequent. ....
I was only talking about std.

For me the standard library is just a library that is guaranteed to be available
with C++. It has only one namespace, not a forest. The name of it is
short. That namespace contains exceptionally *lot* of quite generic names.
So ... loose usage of 'using namespace std' feels not that profitable
and more prone to clashes.

It is possible that you for example use some naming convention that prevents
clashes, for example you use capitalized names. Then you have 'Game::Map'
and it can no way clash with 'std::map'.
 
T

Tobias Müller

Öö Tiib said:
When it just makes overload resolution to fail then that is easy. Then there are
list of ambiguous functions. Function names are only subset of names
in C++ standard library.

I have no compiler at hand currently, but I believe that class or variable
name conflicts produce similar messages.
Sure. Things change. Language evolves, compilers and tools get better. Then
I will relearn. Right now I feel that 'using namespace' does wrong thing that I
don't need.

But that's the case with almost all types of error messages.
Most people abandon lot of C++ features sooner or later.

But in most cases for different reasons:
For example
there are very few who use raw pointer and new[] and delete[] for dynamic
array, majority use std::vector instead.

Because those may be dangerous at _runtime_, that's a different story.
Very rare ever consider overloading
operator,(),

Sure, most don't even use the builtin one. Still it is not dangerous to use
and I would never criticize somone for using it.
operator&&() or operator||().

Probably because it is not possible to produce the same short-circuit
behaviour as with the builtin one. It won't do what everyone expects.
Very rare use throw in destructor,

Can lead to crashes at _runtime_, if done while stack unwinding.
very rare call virtual functions from constructor or from destructor. etc.

Because it usually makes no sense. Virtual functions are designed to be
virtual, and if they are called statically, they don't do the right thing.
These are all features that compile to valid code in C++ language.
However ... the behavior may be confusing and error prone so ... lot of
people have abandoned those.

People who avoid that 'using namespace' do it for similar reasons. It makes
code fragile.

But all those other features are either dangerous at runtime or make the
(existing) code difficult to understand. 'using namespace' is neither
dangerous, nor confusing for reading existing code. It may require changes
in the future, when name clashes are introduced, but I find that
acceptable.
There we differ. There are too lot of convenient short names in namespace std
to demand that these names are sacred and should never be used otherwise.
Why authors of C++ did put them into that namespace? I think because they
saw as well that these names can mean entirely other things in some other
context.


That last sentence was the only one that did matter to me. Most uses of some
name defined are in the scope where it was defined, IOW within the
namespace of that name. Using it qualified within the same namespace is
strange.

I never said you must always use "using namespace". Use it where
appropriate.
I myself have almost never conflicts with std. That's why I find it strange
that everytime it is mentioned here someone comments on that even if it's
completely irrelevant.
That I may never use any name from std namespace for something unqualified


No, std::map and std::unordered_map are similar containers. I mean things with
clear domain-specific meaning like 'building::floor::map'. That is not like
std::map at all. It prevents unqualified usage of std::map and maybe std::floor
by hiding those.

If you use names from namespace std alot in a different contexts, then you
probably should not use "using namespace std", but not everyone does that.

But you are right, it would be nice if we could hide specific identifiers
from a "using namespace".
The author of such unqualified usage may be some other person.
So the author of that map may need to use 'building::building_floor::floor_map'
or something like that to avoid breaking (or maintaining) other person's code.
In short ... stammer, just to legalize saving 5 characters 'std::' in few places.


Hmm. There are two things that can cause something to break. Someone did
apply too lot of power or that the something was fragile and easy to break.

Someone wrote code that stops compiling because I started include <thread> in
my class header that they happen to include. Did it break because of their usage
of 'using namespace std' did make their code fragile or did it break because of
my oh so "evil" change?

Either, it's in the same project, then it's your responsability that
everything compiles after your change. Or it's a different project, then
it's the responsability of the person that introduced the new version of
your header.

Changes in header files are almost never without danger if you don't know
all client files.
For me the standard library is just a library that is guaranteed to be available
with C++. It has only one namespace, not a forest. The name of it is
short. That namespace contains exceptionally *lot* of quite generic names.
So ... loose usage of 'using namespace std' feels not that profitable
and more prone to clashes.

It is possible that you for example use some naming convention that prevents
clashes, for example you use capitalized names. Then you have 'Game::Map'
and it can no way clash with 'std::map'.

I have rarely seen lowercase class names except the ones in the standard
library. Also, 99% of the code I work with uses CamelCase names.

At work, we even use Uppercase names for method and function names.

All this is not specifically because of name conflicts, but readability
(CamelCase vs under_score) or convention (Microsoft class and function
names are always Uppercase).

That it helps avoiding conflicts is just a bonus.

My point is, that the feature is not dangerous per se.

Tobi
 
B

Balog Pal

That's a rule I was unaware of. I happily break it, all the time.

Guess then the other people working on the same code are not so happy
;-). Believe me, it's pretty important one both for functions and
operators. (The usual flamewars about evilness of operator overloading
ar normally based on examples where this rule is broken.)
 
B

Balog Pal

Are you being sarcastic? It is good example.

no. I meant it literally. Unfortunately a written newsgroup is not the
best medium for discussion, on a live seminar it would just rock. :)
What? You must always know what the tools that you use do. There are no
universal rules in existence what every function or member function or
functor that happens to have name 'equal' and happens to accept 3
parameters should do.

Well, really, the rule is more general and versed as "Say what you mean,
mean what you say." Guess you read it in several books including
Meyers'. And the extension of it is to mean the same for other people,
not just you (/the original writer).

It is pretty fundamental in quality of code/product and deviations
create opportunity for bugs. One major aspect of code reviews is to
ensure it is observed. If the code reads ambiguous, let alone does not
what it suggests, it's a problem in its own right, and better be fixed
on entry.
 
B

Balog Pal

Except that "equal()" does *not* do that.

Ok, you're right, and I keep temporarily forgetting that the original
content of std:: it broken in sooo many ways. Including major areas like
naming stuff, consistency, and having introduced an 'iterator' concept
that really is modeled on the pointer pattern rather than the iterator.

I normally don't use the original algos in std:: but similar versions
taking a collection or a Range object instead of a pair of "iterator"s.

Those who actually work with originals are hopefully wide aware that
most times you use two arguments to pass the really one piece of info
you have at hand.

With that addition stick with the semantics posted above (beat me for
poor phrasing ;)
Without the prefix we are left wondering what it actually does. We might
*guess* what it does (ie. just compare the three values to the others)
but, as you wonderfully demonstrate, we would be guessing wrong.

If the example is taken not in abstract discussion, but read in actual
code, where you see what is actually passed, the guessing disappears for
good.
Using the prefix all ambiguity and guessing is removed. We know exactly
what it does, and we know it immediately, without having to search for
the definition of said function.

I keep with my original opinion, that in the context of the project it
is fairly redundant.

OTOH, I have to mention that I'm NOT against using std:: prefix on
*rarely* used or especially broken stuff of the library, and most of the
content in <algorithm> applies.

I DO mind spelling std::vector, string, map and many others that are
generally used, and if the project uses those for different purposes, it
will lead to massive confusion without a good reason. one not really
addressed by prefixes.
 
B

Balog Pal

Example from my sad practice: some non-std::ref (a member function accepting
same argument) has been assumed by compiler into that std::bind. The error
messages are strange and fail to tell anything about 'ref'. If to qualify that
'ref' then the problems disappear. Also, problems disappear if to rename that
member function. That however is not what mine (non-genius) C++ programmer
noob tries.

But what is the root cause? Not having that 'ref' thing in the wild?
What it does? I had situation where several libraries provided ref, but
all did the same thing -- so it worked fine with any, or if name was
ambiguous, it was properly reported. (IMO a direct name clash is not
hard to report, and is useful even it the poorest form, while better
compilers like gcc provide the list of candidates right there).

IMO it is part of good practice to for project management to avoid name
clashes with stuff under control (if that ref class is local, I'd remove
or rename it on discovery), or with third-party stuff have a policy and
known clashes short list compiled. (the policy may be "using directive
forbidden, all names must be used fully qualified", just it better be
considered per library with idea on costs/profits -- and likely limited
to rarely used ones.)
He thinks that he misunderstood something about how std::bind or
std::ref works. Googles and reads. Tries different things. Finally, when he
asks for help frustrated the code is actually wrong too. Then I have to
understand what he wanted to achieve, what he has written and what there
actually should be.

On the bright side we have lambda already (I just discovered it works
fine even in VS2010), that can replace so many uses of bind.
If he had never used 'using namespace std' then he could had written it
himself under 5 minutes yes. So for him and me that 'using namespace std'
is harmful, for you it apparently is not.

On the practical side, let's mention good alternatives. we can make a
list of using declarations for the most commonly used things, and
replace the using directive with that #include -- or use such include in
the first place instead of the direct ones. it's not hard to avoid
clashes on the closed set of names, and no more noise is needed further on.
 
B

Balog Pal

But do not you feel that something has been 'broken' if it needs 'fixing'?

No. That argument implies extreme generalisation. As if we should walk
with open umbrellas all the time. Instead of picking them only when the
forecast suggests and open them only in the street when it actually rains.

Using prefixes is excess noise that hurts reading and writing. It is an
ongoing cost you pay. I don't mind paying when it is needed, but not out
of some general fear or out of ignorance.
'using namespace' on the other hand is lazy shortcut that imports whole
namespace, documents nothing and unless it causes clashes immediately it
works like time bomb that one needs to fix in the future.

I agree that using directive damn powerful and it must come with the
question 'you surely know all the names dragged in or have other means
to be sure the effect will be benign.'

But the answer to the latter is pretty often an positive yes. Maintained
by a simple set of guidelines.

IMO the simple name hiding rules of C++ work pretty fine for most cases,
and situations where you actually need a qualification are rare. (so
they also serve as attention drawing, that non-default thing happens!)
No. That is the other edge way how to go too far with namespaces by
by splitting it into small namespaces with long names. C++ has
fortunately a cure to it:

namespace region = thatdomain::thatsubdomain::thatsubdubdomain;

That is cure only for forced 3rd party stuff, if needed for homegrown,
I'd consider different ones.

I recall CORBA used to generate such nested madness. While healthy
librarues stick with a single public namespace name, and even provide
some #define to turn that off.
 
B

Balog Pal

There we differ. There are too lot of convenient short names in namespace std
to demand that these names are sacred and should never be used otherwise.
Why authors of C++ did put them into that namespace? I think because they
saw as well that these names can mean entirely other things in some other
context.

There wasn't any considerable alternatives. The standard came pretty
late to C++, and any existing code was not to be broken.

Since then quite passed, and new code written, that is aware of
existence of std:: IMO has not much excuse to just ignore names.

Wasn't it your example with the non-standard ref class? That approach is
only good to create trouble.
 
B

Balog Pal

It is possible that you for example use some naming convention that prevents
clashes, for example you use capitalized names. Then you have 'Game::Map'
and it can no way clash with 'std::map'.

Actually that is what most, if not all places I saw do. All lowercase
names are used only in locations not clashing with all-lower libraries.
(or the all-lower names use special form/prefix)

That was the case well before the C++ standard was created, due to the C
library and its followers.
 
Ö

Öö Tiib

But all those other features are either dangerous at runtime or make the
(existing) code difficult to understand. 'using namespace' is neither
dangerous, nor confusing for reading existing code. It may require changes
in the future, when name clashes are introduced, but I find that
acceptable.

When I look someone's code with what I am not too familiar with then it can
be indeed harder to get for me what that fill(), reverse(), rotate() or generate()
there does. When it is qualified std::fill(), std::reverse(), std::rotate()or
std::generate() then the code is simpler to understand for me, even with no
compiler errors.

It may be totally irrelevant for you if you and your team uses capitalized
function and member function names so fill() means std::fill() and some
non-standard fill in same scope is spelled 'Fill()'.

On that case I also see why you consider 'using namespace std;' less harmful
than 'using namespace ThatOther;'. The names from ThatOther namespace
may cause more headache for you than the ones from std.

....
My point is, that the feature is not dangerous per se.

Not dangerous like throwing from destructor. Hopefully you see too that
(depending on naming conventions used) the outcome may become
confusing.
 
D

Dombo

Guess then the other people working on the same code are not so happy
;-). Believe me, it's pretty important one both for functions and
operators. (The usual flamewars about evilness of operator overloading
ar normally based on examples where this rule is broken.)

Rule#1: If the code was hard to write it should be hard to understand.
 
Ö

Öö Tiib

No. That argument implies extreme generalisation. As if we should walk
with open umbrellas all the time. Instead of picking them only when the
forecast suggests and open them only in the street when it actually rains..

Yes ... however I feel it other way around that using directive opens up
such (big and on lot of circumstances tedious) umbrella that saves one from
qualifying lot of names that he even does not plan to use. Using
declaration you mentioned in other answer feels lot more like correct tool.
Using prefixes is excess noise that hurts reading and writing. It is an
ongoing cost you pay. I don't mind paying when it is needed, but not out
of some general fear or out of ignorance.

I actually use qualified names only in few places where i import those
into context and often rename them. So if coding standard say the
types have to be capitalized then something like:

surrounding_context // namespace, class, function
{
typedef unsigned int Code;
typedef std::pair<Code, std::string> CodeName;
typedef std::vector<CodeName> CodeNames;
// ...
// rest of the code does not need to mention
// vector or pair at all, it deals with CodeNames
// of the context.
}

See, only 3 times typed 'std::' so 'using namespace std;' would save nothing
and can be itself considered excess noise and bloat.
I agree that using directive damn powerful and it must come with the
question 'you surely know all the names dragged in or have other means
to be sure the effect will be benign.'

But the answer to the latter is pretty often an positive yes. Maintained
by a simple set of guidelines.

The sub-thread here was more about 'using namespace std' and it is quite
frequent that I do not even remember if some fold_case() was in std or boost
or in both or in neither. When I don't know it then majority of my coworkers
don't and so the positive "yes" is somewhat questionable about std.
IMO the simple name hiding rules of C++ work pretty fine for most cases,
and situations where you actually need a qualification are rare. (so
they also serve as attention drawing, that non-default thing happens!)

What is simple for us is not so simple for novice. Sometimes they are quite
deeply confused that using same name in inner scope (say derived class)
just hides name in outer scope (say base class) and no diagnostics nor
clashes. So it makes sense to avoid hiding names even if the rules are
clear and simple.
That is cure only for forced 3rd party stuff, if needed for homegrown,
I'd consider different ones.

Sure, I would also just call such homegrown tree of namespaces as
"over-engineered" in review and suggest to flatten it down.
I recall CORBA used to generate such nested madness. While healthy
librarues stick with a single public namespace name, and even provide
some #define to turn that off.

Yes, the open source works often started because someone tried to do
something great in different (hopefully better) way. Sometimes the results
did prove that the way was not that good. So those works still serve as
very good examples of ways that are worth to avoid.

The niche of CORBA is unfortunately still not filled with something as
useful, so people sometimes have to use it for real.
 
B

Balog Pal

The sub-thread here was more about 'using namespace std' and it is quite
frequent that I do not even remember if some fold_case() was in std or boost
or in both or in neither. When I don't know it then majority of my coworkers
don't and so the positive "yes" is somewhat questionable about std.

Here I meant guidelines we discussed on other branch, like not having
all-lowercase names at the namespace level. So the possible hiding is
limited to local names, and can be handled easily.
What is simple for us is not so simple for novice. Sometimes they are quite
deeply confused that using same name in inner scope (say derived class)
just hides name in outer scope (say base class) and no diagnostics nor
clashes. So it makes sense to avoid hiding names even if the rules are
clear and simple.

With this I strongly disagree. The hiding rule is overly simple as it
stands (the new introduced name hides all instances of the same name). I
recall myself debating it and push for more refined versions, but since
was convinced that this simplicity serves better.

Yes, it has cases where confusing novices, but the mitigation is not
avoiding the problem, but pushing to educate those novices until they
get it. By now we have a good collection of the top accidents, so it can
be presented as 'gotcha'.

And if someone can't get as much as hiding, I would not grant him code
check-in rights.
 
J

Jorgen Grahn

Guess then the other people working on the same code are not so happy
;-). Believe me, it's pretty important one both for functions and
operators.

I guess what I'm saying is I don't believe you. I never heard of such
a rule; do you have a reference?

To elaborate a bit: if we're talking free functions (and I believe we
were) my naming is designed to make the calling code easy to read.
For example, one common form is verb(object).

If a verb can have different meanings in different context (and that's
true for a lot of verbs!) that doesn't stop me from using it.
In my book, smoke(Cigarette) and smoke(Pork) doesn't have to have
any semantics in common.

Of course, if I can lean on an existing convention, I do. It's one
of the forgotten benefits of the standard library -- it's full of
conventions you can reuse.

/Jorgen
 
I

Ian Collins

Jorgen said:
I guess what I'm saying is I don't believe you. I never heard of such
a rule; do you have a reference?

It strikes me as a common sense rule to avoid confusing callers.
To elaborate a bit: if we're talking free functions (and I believe we
were) my naming is designed to make the calling code easy to read.
For example, one common form is verb(object).

If a verb can have different meanings in different context (and that's
true for a lot of verbs!) that doesn't stop me from using it.
In my book, smoke(Cigarette) and smoke(Pork) doesn't have to have
any semantics in common.

Of course, if I can lean on an existing convention, I do. It's one
of the forgotten benefits of the standard library -- it's full of
conventions you can reuse.

One of which is all overloads have the same semantics. Can cite a
counterexample?
 
I

Ian Collins

Paavo said:
Not exactly overload, but close: std::numeric_limits<T>::min() gives the
smallest expressible number for type T - except if T happens to be double
or float, in which case min() returns something totally different. Bitten
several times by this.

Me too! That is probably a good example of why the convention should be
adhered to.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top