Using std Namespace [duplicate]
Asked Answered
C

16

126

There seem to be different views on using 'using' with respect to the std namespace.

Some say use ' using namespace std', other say don't but rather prefix std functions that are to be used with ' std::' whilst others say use something like this:

using std::string;
using std::cout;
using std::cin;
using std::endl;
using std::vector;

for all the std functions that are to be used.

What are the pros and cons of each?

Crissman answered 12/8, 2009 at 8:59 Comment(3)
See also How do you properly use namespaces in C++?Glossematics
And Why is “using namespace std” considered bad practice?Glossematics
And How to resolve a name collision between a C++ namespace and a global function?Glossematics
J
153

Most C++ users are quite happy reading std::string, std::vector, etc. In fact, seeing a raw vector makes me wonder if this is the std::vector or a different user-defined vector.

I am always against using using namespace std;. It imports all sorts of names into the global namespace and can cause all sorts of non-obvious ambiguities.

Here are some common identifiers that are in the std namespace: count, sort, find, equal, reverse. Having a local variable called count means that using namespace std won't enable you to use count instead of std::count.

The classic example of an unwanted name conflict is something like the following. Imagine that you are a beginner and don't know about std::count. Imagine that you are either using something else in <algorithm> or it's been pulled in by a seemingly unrelated header.

#include <algorithm>
using namespace std;

int count = 0;

int increment()
{
    return ++count; // error, identifier count is ambiguous
}

The error is typically long and unfriendly because std::count is a template with some long nested types.

This is OK though, because std::count goes into the global namespace and the function count hides it.

#include <algorithm>
using namespace std;

int increment()
{
    static int count = 0;
    return ++count;
}

Perhaps slightly surprisingly, this is OK. Identifiers imported into a declarative scope appear in the common namespace that encloses both where they are defined and where they are imported into. In other words, std::count is visible as count in the global namespace, but only inside increment.

#include <algorithm>

int increment()
{
    using namespace std;
    static int count = 0;
    return ++count;
}

And for similar reasons, count is ambiguous here. using namespace std doesn't cause std::count, hide the outer count as it might be expected. The using namespace rule means that std::count looks (in the increment function) as though it was declared at the global scope, i.e. at the same scope as int count = 0; and hence causing the ambiguity.

#include <algorithm>

int count = 0;

int increment()
{
    using namespace std;
    return ++count; // error ambiguous
}
Jamaaljamaica answered 12/8, 2009 at 9:12 Comment(12)
but it types soooo much easier without the std:: prefix!Caviar
@xtofl: No, it doesn't. Five characters are not that relevant when typing, but these five chars might be very relevant when reading. And ease of reading counts much more than ease of typing for source code, as code is much more read than written.Joh
You could add that the using statement behaves correctly with scope rules.Yep
But if you have identifiers like count, sort, etc. being used along with "using namespace std;" you'll get an error about a naming conflict if you try to use the name in the std namespace and you'll have to qualify it, just like if you didn't have the directive. So you've really lost nothing with the directive, it's just that in this specific instance it hasn't bought you anything either.Collective
@Martin York: Updated with examples illustrating scoping rules. @Michael Burr: That's arguably not so bad, what I really don't like is where the error messages for simple mistakes get a lot harder to interpret, or where they don't happen at all. For example, if a function is believed to be in scope, but isn't and a std:: function is, rather than getting a helpful 'identifier not recognized' error you often end up with a more obscure 'can't convert argument X' or 'unable to generate function from template' style error. Worse is if a wrong function gets called silently. It's rare, but happens.Jamaaljamaica
@Charles - the possibility of calling the wrong function silently is a legitimate item - but as you mention, it's rare and I'm not sure the danger warrants a 'ban' on "using namespace std;". But I'll grant that it's a legitimate opinion. I'm less convinced about the confusing error messages - those occur because compilers produce confusing error messages for templates (though they're getting better), and really has nothing to do with the using-directive. I don't think anyone would say that templates should never be used since they can generate difficult to decipher errors.Collective
@Michael Burr: It may just be my own personal war, but I really do think that the confusing error messages is a significant problem especially for beginners. using namespace std; is frequently sold as an aid to beginners and yet I've often seen instances where it has cause reams of confusing errors.Jamaaljamaica
As an experiment, I wrote a function called equals which took 3 doubles. I then called it with valid parameters but deliberately misspelled it equal. Without u n s; I received a simple message "'equal' was not declared in this scope". With it, I got 27 lines of messages about 2 errors such as "'double' is not a class, struct, or union type" and "'__simple' is not a valid template argument for type 'bool' because it is a non-constant expression". Experienced C++ developers may have no problems wading through this to find the root cause but most beginners would be left stumped. (gcc 4.4.0)Jamaaljamaica
Worthwhile to note that if you have this: int swap; using namespace std; int main() { ::swap = 1; } it's always non-ambiguous: Explicitly specifying the scope will search the namespaces put with using directives - but it won't ever cause a conflict with an existing declaration. This only happens with unqualified name lookupRiendeau
Well, am surprised no one discussed about the option of using std::xxx;. It doesn't do namespace pollution, writing code will be shorter and I think copy is lot more readale than std::copy.Lepton
Just to join this convo late, if you are using an IDE (eclipse) typing out "std::" will then bring up a list of all possible choices in that name space. With the write tools the longer looking code is actually a lot less typing!Magnien
@sbi: I'd argue that some code is actually easier to read, when it isn't cluttered with std:: all over the place. The same way as too long identifier names (even if they are very descriptive) hurt readability.Importance
C
46

Excluding the basics (Having to add std:: infront of all stl objects/functions and less chance of conflict if you don't have 'using namespace std')

It is also worth noting that you should never put

using namespace std

In a header file, as it can propagate to all files that include that header file, even if they don't want to use that namespace.

In some cases it is very beneficial to use things like

using std::swap

As if there is a specialized version of swap, the compiler will use that, otherwise it will fall back on std::swap.

If you call std::swap, you always use the basic version, which will not call the optimized version (if it exists).

Comptom answered 12/8, 2009 at 9:7 Comment(3)
+1 for mentioning that u n s can propagate. Just to note that it can also worm its way into correctly constructed headers: They just have to be included after a rogue header.Rascality
But if you are defining a swap or move (or hash, less etc.) specialization, you should be putting that specialization into namespace std anyway. For instance: namespace std {template<> class hash<X> {public: size_t operator()(const X&) const};} class X: {friend size_t std::hash<X>::operator()(const X&)};Publish
@AJMansfield, putting swap overloads into std namespace is not recommended, see #14403490Shandeigh
C
28

First, some terminology:

  • using-declaration: using std::vector;
  • using-directive: using namespace std;

I think that using using-directives are fine, as long as they aren't used at the global scope in a header file. So having

using namespace std;

in your .cpp file isn't really a problem, and if it turns out to be, it's completely under your control (and it can even be scoped to particular blocks if desired). I see no particlar reason to clutter up the code with a slew of std:: qualifiers - it just becomes a bunch of visual noise. However, if you're not using a whole bunch of names from the std namespace in your code, I also see no problem with leaving out the directive. It's a tautology - if the directive isn't necessary, then there's no need to use it.

Similarly, if you can get by with a few using-declarations (instead of using-directives) for specfic types in the std namespace, then there's no reason you shouldn't have just those spefcific names brought into the current namespace. By the same token, I think it would be crazy and a bookkeeping hassle to have 25 or 30 using-declarations when a single using-directive would do the trick just as well.

It's also good to keep in mind that there are times when you must use a using-declaration. Refer to Scott Meyers' "Item 25: Consider support for a non-throwing swap" from Effective C++, Third Edition. In order to have a generic, templated function use the 'best' swap method for a parameterized type, you need to make use of a using-declaration and argument dependant lookup (aka ADL or Koenig lookup):

template< typename T >
void foo( T& x, T& y)
{
    using std::swap;     // makes std::swap available in this function

    // do stuff...

    swap( x, y);         // will use a T-specific swap() if it exists,
                         //  otherwise will use std::swap<T>()

    // ...
 }

I think we should look at the common idioms for various languages that make significant use of namespaces. For example, Java and C# use namespaces to a large extent (arguably moreso than C++). The most common way names within namespaces are used in those languages is by bringing them into the current scope en masse with the equivalent of a using-directive. This doesn't cause wide-spread problems, and the few times it is a problem are handled on an 'exception' basis by dealing with the names in question via fully-qualified names or by aliasing - just like can be done in C++.

Herb Sutter and Andrei Alexandrescu have this to say in "Item 59: Don't write namespace usings in a header file or before an #include" of their book, C++ Coding Standards: 101 Rules, Guidelines, and Best Practices:

In short: You can and should use namespace using declarations and directives liberally in your implementation files after #include directives and feel good about it. Despite repeated assertions to the contrary, namespace using declarations and directives are not evil and they do not defeat the purpose of namespaces. Rather, they are what make namespaces usable.

Stroupstrup is often quoted as saying, "Don’t pollute the global namespace", in "The C++ Programming Language, Third Edition". He does in fact say that (C.14[15]), but refers to chapter C.10.1 where he says:

A using-declaration adds a name to a local scope. A using-directive does not; it simply renders names accessible in the scope in which they were declared. For example:

namespaceX {
    int i , j , k ;
}

int k ;
void f1()
{
    int i = 0 ;

    using namespaceX ; // make names from X accessible

    i++; // local i
    j++; // X::j
    k++; // error: X::k or global k ?

    ::k ++; // the global k

    X::k ++; // X’s k
}

void f2()
{
    int i = 0 ;

    using X::i ; // error: i declared twice in f2()
    using X::j ;
    using X::k ; // hides global k

    i++;
    j++; // X::j
    k++; // X::k
}

A locally declared name (declared either by an ordinary declaration or by a using-declaration) hides nonlocal declarations of the same name, and any illegal overloadings of the name are detected at the point of declaration.

Note the ambiguity error for k++ in f1(). Global names are not given preference over names from namespaces made accessible in the global scope. This provides significant protection against accidental name clashes, and – importantly – ensures that there are no advantages to be gained from polluting the global namespace.

When libraries declaring many names are made accessible through using-directives, it is a significant advantage that clashes of unused names are not considered errors.

...

I hope to see a radical decrease in the use of global names in new programs using namespaces compared to traditional C and C++ programs. The rules for namespaces were specifically crafted to give no advantages to a ‘‘lazy’’ user of global names over someone who takes care not to pollute the global scope.

And how does one have the same advantage as a 'lazy user of global names'? By taking advantage of the using-directive, which safely makes names in a namespace available to the current scope.

Note that there's a distinction - names in the std namespace made available to a scope with the proper use of a using-directive (by placing the directive after the #includes) does not pollute the global namespace. It's just making those names available easily, and with continued protection against clashes.

Collective answered 12/8, 2009 at 16:45 Comment(8)
With regards to your last point: Java and C# also have much neater namespaces. If everything in the BCL lived in System, "using System" would cause just as much trouble as "using namespace std".Basipetal
But the Java and C# programs that I see typically bring in all the namespaces they use - not just "System" (or its equivalent). So instead of a single using directive that brings in all the names used, there are 5 or 10 that do more or less the same thing. Also, does "using namespace std;" really cause that much trouble?Collective
The problem is that std has too many common names and that including one standard header may includes all the other one. We don't have a good control on what is imported, there are too many risks. I don't know enough about Java and C#, but I know about Ada which has a far better module system than C++ and where importing names is usually frowned upon. In general, its first a matter of naming convention (I've seen people using prefix as well as namespace, not importing doesn't make sense) then of style.Savior
I'm still not convinced that this is a real-world problem. I see using-directives used all the time without severe drawbacks. Then again, I have no problem with not using them. I just prefer that std:: qualifiers not clutter up the code - there are other ways to avoid that (using-declarations or typedefs usually do the trick).Collective
@Michael, do you accept my word that I've spend time to remove using-declarations because of conflicts? list is a natural identifier for identifying list in a lisp interpreter. Now, if you are using naming conventions which naturally prevent clashes with the standard library (says type name starting with an upper case letter...), its normal that you don't see problems. You are lucky, C++0X has dropped the concepts, you won't get such names soon...Savior
@Savior - I will certainly accept your word that it's caused you problems. However, I reserve the right to stubbornly hold to my opinion, even if it's wrong :). To paraphrase Bart Simpson, I won't promise to try to stop needlessly throwing "using namspace std;" into my code, but I'll try to try.Collective
@AProgrammer: you say, "list is a natural identifier for identifying list in a lisp interpreter" - but having the "using namespace std;" directive doesn't prevent you from declaring your natural identifier 'list' - it's just that if you do, you can no longer use std::list without qualifying it. That's no different than if there is no "using namespace std;" directive. Or am I missing something?Collective
@Michael, I've modified my answer to explain what occurred. The story is too long for a comment.Savior
S
17

Never use using namespace at global scope in an header file. That can leads to conflict and the person in charge of the file where the conflict appears has no control on the cause.

In implementation file, the choices are far less well cut.

  • Putting a using namespace std brings all the symbols from that namespaces. This can be troublesome as nearly no body know all the symbols which are there (so having a policy of no conflict is impossible to apply in practice) without speaking of the symbols which will be added. And the C++ standard allows an header to add symbols from other headers (the C one doesn't allow that). It still can work well in practice to simplify the writing in controlled case. And if an error occur, it is detected in the file which has the problem.

  • Putting using std::name; has the advantage of simplicity of writing without the risk of importing unknown symbols. The cost is that you have to import explicitly all wanted symbols.

  • Explicitly qualifying add a little clutter, but I think it is the less trouble some practice.

In my project, I use explicit qualification for all names, I accept using std::name, I fight against using namespace std (we have an lisp interpreter which has his own list type and so conflict is a sure thing).

For other namespaces, you have also to take into account the naming conventions used. I know of a project which use namespace (for versionning) and prefix on names. Doing a using namespace X then is nearly without risk and not doing it leads to stupid looking code PrefixNS::pfxMyFunction(...).

There are some cases where you want to import the symbols. std::swap is the most common case: you import std::swap and then use swap unqualified. Argument dependent lookup will find an adequate swap in the namespace of the type if there is one and fall back to the standard template if there is none.


Edit:

In the comments, Michael Burr wonders if the conflicts occur in real world. Here is a real live exemple. We have an extension language with is a lisp dialect. Our interpreter has an include file, lisp.h containing

typedef struct list {} list;

We had to integrate and adapt some code (which I'll name "engine") which looked like this:

#include <list>
...
using std::list;
...
void foo(list const&) {}

So we modified like this:

#include <list>

#include "module.h"
...
using std::list;
...
void foo(list const&) {}

Good. Everything work. Some months later, "module.h" was modified to include "list.h". The tests passed. "module" hadn't be modified in a way that affected its ABI, so "engine" library could be used without re-compiling its users. Integration tests were OK. New "module" published. Next compilation of engine broke when its code hasn't be modified.

Savior answered 12/8, 2009 at 9:16 Comment(5)
One of the controlled case where I think using namespace is acceptable is in publishing code. The simplification facilitates the layout of the page and help to concentrate on the exposed point. The drawback is that it doesn't really show a good practice, so I wouldn't use it in books for beginner.Savior
I think typing std:: is a small price to pay for clarityCrissman
@paoloricardo: On the other hand, I think having std:: show up all over the place is unnecessary visual clutter.Collective
@Michael: you pays your money and you make your choice!Crissman
Thanks for taking the time to add the details of the problem you ran into.Collective
J
4

If you don't have a risk of name conflicts in your code with std and other libraries you can use :

using namespace std;

But if you want know precisely the dependancy of your code for documentation or there is a risk of name conflicts use the other way :

using std::string;
using std::cout;

The third solution, don't use these solutions and write std:: before each use in code brings you more security but, maybe a little heaviness in the code...

Josephinejosephson answered 12/8, 2009 at 9:16 Comment(0)
P
4

Both

using std::string;

and

using namespace std;

add some symbols (one or lots of) to the global namespace. And adding symbols to global namespace is something you should never do in header files. You have no control who will include your header, there are lots of headers that include other headers (and headers that include headers that include headers and so on...).

In implementation (.cpp) files it's up to you (only remember to do it after all #include directives). You can break only code in this specific file, so it's easier to manage and find out the reason of name conflict. If you prefer to use std:: (or any other prefix, there can be many namespaces in your project) before indentifiers, it's OK. If you like to add identifiers you use to global namespace, it's OK. If you want to bring whole namespace on your head :-), it's up to you. While the effects are limited to single compilation unit, it's acceptable.

Phillida answered 12/8, 2009 at 9:44 Comment(0)
A
4

For me, I prefer to use :: when possible.

std::list<int> iList;

I hate to write :

for(std::list<int>::iterator i = iList.begin(); i != iList.end(); i++)
{
    //
}

Hopefully, with C++0x I would write this:

for(auto i = iList.begin(); i != iList.end(); i++)
{
    //
}

If the namespace is very lengthy,

namespace dir = boost::filesystem;

dir::directory_iterator file("e:/boost");
dir::directory_iterator end;

for( ; file != end; file++)
{
    if(dir::is_directory(*file))
        std::cout << *file << std::endl;
}
Addams answered 12/8, 2009 at 9:57 Comment(3)
@AraK: namespace dir = boost::filesystem; I guess this is an alias?Crissman
@paoloricardo: Yes that#s what it is.Joh
Iterators should be incremented with ++i, not i++ because, if it is even defined, creates an unnecessary temporary copy of the iterator.Olein
J
2

You should never be using namespace std at namespace scope in a header. Also, I suppose most programmers will wonder when they see vector or string without std::, so I think not using namespace std is better. Therefor I argue for never be using namespace std at all.

If you feel like you must, add local using declarations like using std::vector. But ask yourself: What's this worth? A line of code is written once (maybe twice), but it's read ten, hundred or thousand times. The saved typing effort be adding a using declaration or directive is marginal compared to the effort of reading the code.

With that in mind, in a project ten years ago we decided to explicitly qualify all identifiers with their full namespace names. What seemed awkward at first became routine within two weeks. Now, in all projects of that whole company nobody is using using directives or declarations anymore. (With one exception, see below.) Looking at the code (several MLoC) after ten years, I feel like we made the right decision.

I've found that usually, those who oppose banning using usually haven't tried it for one project. Those who have tried, often find it better than using directives/declarations after a very short time.

Note: The only exception is using std::swap which is necessary (especially in generic code) to pick up overloads of swap() that cannot be put into the std namespace (because we aren't allowed to put put overloads of std functions into this namespace).

Joh answered 12/8, 2009 at 9:58 Comment(10)
A specialization of std::swap would be a complete specialization - you can't partially specialize function templates. Any program is allowed to partially specialize any standard library template so long as that specialization depends on a user-defined type.Jamaaljamaica
@Charles: Yes, you're right, of course, there's not FTPS. And I can specialize templates within std, but not overload. Sorry for that brainfart. I'll correct the post.Joh
I don't think the intention of the using namespace directive was to make typing either; rather, it was to make reading easier, because, as you say, that code will have to be read dozens, hundreds or thousands of times. And for some people, it reads much easier with less std:: clutter. But that probably comes down to personal perceptive ability; some people filter std:: away or even need it for guidance (like serifs), others stumple on it and feel like on a bumpy road.Upsydaisy
@Lumi: Whether you like shorter or longer prose is subjective, but the prefixes objectively add clarity to the code.Joh
@sbi: No, that's not objective. It depends upon whether or not you think the std:: is helpful, or clutter. More clutter -> less clarity.Koonce
@Joshua: Can we agree that the compiler is objective?Joh
@sbi: Maybe. ;-) Different compilers will handle things differently. Sometimes right, sometimes wrong, sometimes better or sometimes worse (subjectively.) It's very difficult to make a universal statement, which is ok, because I don't like to be told how I "must" do something, unless it's really undeniably better.Koonce
@Joshua: Sigh. Can we agree that a fully standard-conforming is objective? (Also note that my answer starts with "you should..." and that I was once on your side of the argument.)Joh
@Joh Sure, we can agree that standard-conformance can be objectively evaluated. But what is your point -- I'd be interested to know how you go from there to "prefixes objectively add clarity to the code"? I wasn't really commenting on your original answer, only your last comment to Lumi. Your original answer is framed as your opinion and relates an interesting experience that will help people make up their own minds, so thanks for that.Koonce
@Joshua: My point is that compilers prefer the clarity of prefixes. (They sometimes "get confused" and call an unintended overload if you omit them. They always call the right one if you prefix with the namespace.)Joh
E
2

Namespaces keep code contained to prevent confusion and pollution of function signatures.

Here's a complete and documented demo of proper namespace usage:

#include <iostream>
#include <cmath>  // Uses ::log, which would be the log() here if it were not in a namespace, see https://mcmap.net/q/138255/-why-is-my-log-in-the-std-namespace

// Silently overrides std::log
//double log(double d) { return 420; }

namespace uniquename {
    using namespace std;  // So we don't have to waste space on std:: when not needed.

    double log(double d) {
        return 42;
    }

    int main() {
        cout << "Our log: " << log(4.2) << endl;
        cout << "Standard log: " << std::log(4.2);
        return 0;
    }
}

// Global wrapper for our contained code.
int main() {
    return uniquename::main();
}

Output:

Our log: 42
Standard log: 1.43508
Edi answered 6/5, 2015 at 2:5 Comment(0)
M
0

using namespace std imports the content of the std namespace in the current one. Thus, the advantage is that you won't have to type std:: in front of all functions of that namespace. However, it may happen that you have different namespaces that have functions of the same name. Thus, you may end not calling the one you want.

Specifying manually which ones you want to import in std prevents that from happening, but may result in a long list of using at the beginning of your file, which some developer will find ugly ;) !

Personally, I prefer specifying the namespace each time I use use a function, except when the namespace is too long, in which case I put some using at the beginning of the file.

EDIT: as noted in another answer, you should never put a using namespace in a header file, as it will propagage to all files including this header and thus may produce unwanted behavior.

EDIT2: corrected my answer, thanks to Charles comment.

Micromho answered 12/8, 2009 at 9:8 Comment(4)
using namespace std; imports the contents of the std namespace into the global namespace. It doesn't change the default namespace. Defining something in the global namespace after a using namespace std won't magically put it into the std namespace.Jamaaljamaica
Sorry, this wasn't what I meant. Thanks for pointing it out, I'll correct my answer.Micromho
Guys: thanks for the responses. It appears that, in general, it is safer to not use 'using namespace std' and avoid creating potential ambiguities. On balance using 'std::xxx' appeals to me more than declaring a list of the various functions at the beginning of the source file since it qualifies unambiguously what one's intent is.Crissman
Quote(except when the namespace is too long). You can use namespace aliasing to help there. 'namespace Rv1 = Thor::XML::XPath::Rules::Light::Version1;' Note aliases and using both obey scoping rules;Yep
C
0

This discussion is going to be alive as long as the IDE you work with is not flexible enough to show or hide the exact information you need.

That is because what you want your code to look like depends on the task at hand.

While creating my source code, I prefer to see exactly which class I'm using: is it std::string, or the BuzFlox::Obs::string class?

When designing the control flow, I'm not even interested in the types of the variables, but I want a focus on if's and while's and continue's.

So this is my advise:

Depending on the audience of your code and the power of your tools, choose the way that either reads easiest, or gives most information.

Caviar answered 12/8, 2009 at 9:56 Comment(0)
L
-1

Much like in Java where you can use either can include java.util.* or simply select each class individually, it depends on style. Note that you don't want one using namespace std at the start of your file/wide scope because you will pollute the namespace and possibly have clashes, defeating the point of namespaces. But if you have a function that uses a lot of STL, it clutters the code to have a jumble of prefixing syntax in your logic and you should probably consider using either using namespace std (when using a variety of classes) or individual usings (when using a few classes often).

Lobo answered 12/8, 2009 at 9:10 Comment(0)
R
-1

There are several ways to fix that.

First: use like what you did.

Second: do namespace S = std;, reducing 2 chars.

Third: use static.

Fourth: don't use names that std uses.

Recluse answered 30/6, 2016 at 13:46 Comment(1)
"Second: do namespace S = std;, reducing 2 chars" ... and add a huge amount of confusion and friction when reading the code? It's not worth it--nobody knows what S::string is, but everyone knows what std::string is. The constant mental translation is a serious burden.Cumquat
W
-1

Beside to the many correct answers here, I want to state an often forgotten detail: The concept of translation units in C++ seems to be misunderstood by many developers due to common coding and linking schemes. It's common for most of us, that .h files are header files and .cpp files yield the implementation details but that's rather a consent than a strict rule of the standard. How you finally compound your translation units is up to you in doubt.

So for instance with UnityBuilds (linking everything to one single translation unit for speed-up and memory purposes), you can no longer rely on the common consent, that using namespace in .cpp files is quite ok in general. Some might argue, that UnityBuilds circumvent several major C++ core philosophies and are therefore a topic on their own, but nevertheless there are further scenarios where similar issues can occur (local includes in functions for instance). Similar issues arise here with the usage of anonymous namespaces by the way.

Since this was an issue to me in the past, I came up with the "inner guideline" to make things as explicit as possible as long as proportionality allows it.

Washko answered 5/11, 2020 at 14:40 Comment(0)
F
-2

What are the pros and cons of each

The only reason to leave off the std:: is that you could, in theory, reimplement all the STL functions yourself. Then your functions could be switched from using std::vector to my::vector without changing the code.

Foliar answered 12/8, 2009 at 16:57 Comment(4)
Namespaces aren't really designed to allow replacement of names with different, but equivalent, functionality. They are designed to prevent unintended name clashes.Collective
Yes, so the only justification for the 'using' directive which breaks this is to allow you to switch functions to a new namespace.Foliar
I think you'd find an awful lot of programmers complaining about what a pain in the ass namespaces are and wanting to throw them out the window if there weren't a using-directive. As far as I know, every language that uses namespaces has something similar to a using-directive to get them out of the way when you want them out of the way. If the directives are useless, why do they exist everywhere?Collective
I think the "using" was intended to allow you to switch to alternate implementations rather than to save typing 3 letters. I like using "std::Foo" because it serves as a contract to the programmer that I am using the normal Foo and they don't have to check. I agree I wouldn't want to have to type "com.microsoft.visual-studio.standard-library.numbers.int foo", some of the iterator declarations in the STL get like this. Python does a nice job of allowing you to pull in decorated or undecorated sets of functions from modules.Foliar
C
-3

Why not for example

typedef std::vector<int> ints_t;
ints_t ints1;
....
ints_t ints2;

instead of the unwieldy

std::vector<int> ints1;
...
std::vector<int> ints2;

I find that much more readable and its my standard for coding.

You can even use it to include some semantic information for the reader. For example, consider the function prototypes

void getHistorgram(std::vector<unsigned int>&, std::vector<unsigned int>&);

which ones the return value?

How about instead

typedef std::vector<unsigned int> values_t;
typedef std::vector<unsigned int> histogram_t;
...
void getHistogram(values_t&, histogram_t&); 
Cloe answered 22/9, 2009 at 23:28 Comment(1)
Good luck to anyone trying to make sense of this codebase. I would prefer to differentiate param/return value data structures with const rather than burying it in some ad-hoc, non-standard typedef.Cumquat

© 2022 - 2024 — McMap. All rights reserved.