2

I have a problem with including header files in C++. As far as I know, it's not a good design to put using namespace std inside header but I got some error when I try to remove it. Here is my code in header file :

#include <iostream>
#include <string>

//using namespace std;
class Messages
{
public:
Messages(string sender, string recipient,int time);
void append();
string to_string();


private:
int time;
string sender;
string recipient;
string text;

};

I did include <string>. However, If I don't use namespace std, all my strings show errors. I do not want to add using namespace std in header file because it's a bad design. So how do I fix it?

Thanks in advance.

TemplateRex
  • 69,038
  • 19
  • 164
  • 304
Yvonne
  • 63
  • 1
  • 4
  • 12
  • 3
    Just wirte `std::string` instead of `string` – Lucas May 22 '13 at 08:23
  • specify namespace: `std::string`. – hmjd May 22 '13 at 08:23
  • 6
    The damage introductory textbooks with `using namespace std;` do ... – Benjamin Bannier May 22 '13 at 08:24
  • 2
    @honk - :D and not just the C++ ones.Almost all textbooks get you started off with such a flawed basic approach, it ruins your workflow later. And its a pain to switch over. – hanut May 22 '13 at 08:33
  • 1
    @HanutSingh: My personal pet peeve is C tutorials using `printf()` for "hello world". I believe `puts()` must be a *very* lonely function indeed. ;-) – DevSolar May 22 '13 at 08:37
  • @DevSolar : True indeed. When I started coding in C many aeons ago, I almost always used `printf()`. Wish I had good old [Google](http://www.google.com) back then. – hanut May 22 '13 at 08:40
  • @HanutSingh: IMO using directives are way to subtle for beginners. Using typedefs would probably a better idea, but I have never seen that one. – Benjamin Bannier May 22 '13 at 08:40
  • @honk: Typedef's would just make it worse. Let me tell you from the standpoint of a long-time maintenance coder: Anything that requires a lookup (or memory) of any kind is a nuisance. Now judge whether you saving a couple of keystrokes while writing the code justifies all the additional "what's this?" during code maintenance. IMHO, it doesn't, and I refrain from `using ...` of any kind, and reserve `typedef` for function pointers (which are hideous, syntactically). Next time I see a `typedef std::vector< std::string > StringVector;`, I swear I'm going to maul somebody. – DevSolar May 22 '13 at 08:46
  • @DevSolar: I agree with you and believe I use using directives exclusively to make functions visible when inheriting. My point was that teaching `using namespace std;` is really the worst idea from a bag of bad ones. – Benjamin Bannier May 22 '13 at 08:50

2 Answers2

5

Just write std::string everywhere.

#include <iostream>
#include <string>

//using namespace std;
class Messages
{
public:
Messages(std::string sender, std::string recipient,int time);
void append();
std::string to_string();


private:
int time;
std::string sender;
std::string recipient;
std::string text;

};

Just as a rule of thumb: whenever (even in .cpp files) you are using any of the data types or algorithms from the Standard Library, just prefix it with std::. It's brief enough to type, and it will save you a world of pain.

There are some reasons for advanced users to use using declarations at function scope, e.g. when you want to overload a function (e.g. swap) from the Standard Library to work with your own data types (inside their own namespaces). See e.g. this Q&A on how that works.

Community
  • 1
  • 1
TemplateRex
  • 69,038
  • 19
  • 164
  • 304
3

The class string is declared inside the namespace std. You have three ways of addressing a class that's inside a different namespace:

  1. By always writing <namespace>::<class>
  2. By explicitly declaring that any reference to <class> actually means 1. above: using <namespace>::<class>;.
  3. By declaring that any reference to a <class> that could not be resolved in the current namespace should also be looked up in an additional namespace: using namespace <namespace>;

Those are sorted in descending order of expressiveness. While 1. is perfectly clear wherever written, 3. can require some looking-up and scratching of heads if you are not familiar with the (possible multiple) namespaces used.

These are also sorted in descending order of typing involved, which is why some people (and especially textbooks) opt for 3.

However, you should never use using ... in a header file, because you are not only messing with the namespace resolution inside your header, but also with that of everyone including your header. This results in namespace collisions, strange errors depending on the order of includes and lots of other headaches. Just don't.

And generally speaking, while there is some pro and con involved with options 1. and 2. in implementation files, option 3. is simply offensive to anyone having to work with your source later on.

DevSolar
  • 67,862
  • 21
  • 134
  • 209