Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

using namespace std; in a header file

So, I have the following in a specification file

#include <string>
#include <fstream>
using namespace std:

class MyStuff
{
    private:

    string name;
    fstream file;
    // other stuff

    public:
    void setName(string);
}

I also have in the implementation file

#include "MyStuff.h"
using namespace std;

void MyStuff::setName(string name);
{
     name = name
}

and in the program file I have...

#include <iostream>
#include <string>
using namespace std;

void main()
{
     string name;
     MyStuff Stuff;

     cout << "Enter Your Name: ";
     getline(cin, name);

     Stuff.setName(name);
}

And I'm gathering that applying "using namespace std;" in a header file is a no-no, and that to fully qualify is the "better" practice; such as std::cout << stuff << endl;

It is my understanding that in order to use a string, it must have the std namespace. Is that true?

If so, in the header file, is more "pure/clean" to do it as...

#include <string>

class MyStuff
{
     std::string name;
}

And, as I understand it currently, using namespace std; across all three files, specification, implementation, and program, essentially layers the three namespaces on top of each other, so if I separately declare string name; within each of the files, the compiler will not know which goes to what. Is that true?

I generally understand that being clear is a "good" thing to do, I am however a little unclear on the specificity of how, and I'm most interested in the deeper "why" that underlies it all.

So my direct question is, in my example provided, what is the "clearest" way to describe the function both for the compiler and for industry "standard"? And, can you direct me to resources that more clearly delineate the reasoning and practical implementation of namespaces.

like image 955
RebelPhoenix Avatar asked Jan 29 '13 04:01

RebelPhoenix


People also ask

Can you put using namespace std in header file?

Since you can't put a namespace using statement at the top level of the header file, you must use a fully qualified name for Standard Library classes or objects in the header file. Thus, expect to see and write lots of std::string, std::cout, std::ostream, etc. in header files.

Why should you never place a using namespace directive inside of a header file?

However you'll virtually never see a using directive in a header file (at least not outside of scope). The reason is that using directive eliminate the protection of that particular namespace, and the effect last until the end of current compilation unit.

Is it OK to use using namespace std?

To put it as an advice: Do not use "using namespace" (std or other) at file scope in header files. It is OK to use it in implementation files.

Where should namespace std be placed?

Use the “using namespace std” statement inside function definitions or class, struct definitions. In doing so the namespace definitions get imported into a local scope, and we at least know where possible errors may originate if they do arise.


2 Answers

Let's say I declare a class string myself. Because I'm a lazy bum, I do so in global namespace.

// Solar's stuff
class string
{
    public:
        string();
        // ...
};

Some time later on, I realize that re-using some of your code would benefit my project. Thanks to you making it Open Source, I can do so:

#include <solarstuff.hpp>
#include <phoenixstuff.hpp>

string foo;

But suddenly the compiler doesn't like me anymore. Because there is a ::string (my class) and another ::string (the standard one, included by your header and brought into global namespace with using namespace std;), there's all kinds of pain to be had.

Worse, this problem gets promoted through every file that includes my header (which includes your header, which... you get the idea.)

Yes I know, in this example I am also to blame for not protecting my own classes in my own namespace, but that's the one I came up with ad-hoc.

Namespaces are there to avoid clashes of identifiers. Your header not only introduces MyStuff into the global namespace, but also every identifier from string and fstream. Chances are most of them are never actually needed by either of us, so why dragging them into global, polluting the environment?

Addition: From the view of a maintenance coder / debugger, foo::MyStuff is ten times more convenient than MyStuff, namespace'd somewhere else (probably not even the same source file), because you get the namespace information right there at the point in the code where you need it.

like image 173
DevSolar Avatar answered Sep 20 '22 17:09

DevSolar


Multiple instances of using namespace std; will not cause any ambiguity. The problem is that that statement imports all the names/types/functions of std into your namespace, and now if you want to name a class string for instance, you will hit into trouble. This is more likely to happen with functions like remove, erase, etc.

The use of it in headers is one level worse because that propagates to all the .cpps that header, without the awareness of person including it. Using it in .cpp atleast needs a conscious choice.

A more complete explanation can be got at Why is "using namespace std" considered bad practice?

An example of issues that might result from this can be found in How to use an iterator? where the OP defines a function distance, and keeps getting the wrong answer. Another example at Confusion about pointers and references in C++

like image 21
Karthik T Avatar answered Sep 18 '22 17:09

Karthik T