3

Possible Duplicate:
reincluding header in implementation

What I am wondering is that it is common practice to not use using namespace xxx in a header file as not to pollute the global namespace. How does this go for #includes?

If I have foo.h and foo.cpp.:

//Foo.h
#ifndef FOO_H_
#define FOO_H_

#include <string>

class Foo
{
  public:
    Foo(std::string * a, std::string * b);
    virtual ~Foo();
};

#endif /* FOO_H_ */

//Foo.cpp
#include <string>
#include <Foo.h>
Foo::Foo(std::string * a, std::string * b)
{
  // TODO Auto-generated constructor stub

}

Foo::~Foo()
{
  // TODO Auto-generated destructor stub
}

Would I really need to #include <string> in both files? Would including it only in the .h or .cpp suffice? (I know both will work, but what is advisable?)


edit, a bit more background information regarding my question.
If I would be using certain classes in my header file (either as variables or method arguments) I would forward declare them in the header file and only include the header file itself in the source file. But this will not work for most STL libs because you can't forward declare class-templates?

Community
  • 1
  • 1
Daan Timmer
  • 14,771
  • 6
  • 34
  • 66
  • 5
    You only need to include it in the header, but it's good to include each thing you need in every file you need it. – chris Nov 05 '12 at 20:50
  • 5
    Forward declare when possible, `#include` when necessary. It can help to greatly reduce your build times. – Chad Nov 05 '12 at 20:55
  • 2
    Include them. The only alternative is forward declaration, and you surely don't want to forward declare `namespace std { template class basic_string; typedef basic_string, std::allocator > string; }`. (I'm not even sure whether this is correct) – Alexandre C. Nov 05 '12 at 20:57
  • 1
    @AlexandreC.: I'm pretty sure that such a forward declaration would technically be undefined behavior. C++03 §17.4.3.1/1 says "It is undefined for a C++ program to add declarations or definitions to namespace `std` or namespaces within namespace `std` unless otherwise specified." – Adam Rosenfield Nov 05 '12 at 21:37

1 Answers1

3

... because you can't forward declare class-templates?

class templates can be forward declared - like non template classes:

// forward declaration
template <typename T>
class C;

However, as @AlexandreC stated in comments, for std::string it would be quite complicated, because std::string is typedef from template <typename,typename,typename> basic_string;.

I write it would be complicated, if it would be allowed. And it is not allowed, see:

According to the C++11 standard, 17.6.4.2.1:

The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std unless otherwise specified.

So, no choice but include <string> in header file for std::string.


For your main question - I would include in source and header files, unless I was pretty sure it would be always included in header file and never removed...

Community
  • 1
  • 1
PiotrNycz
  • 23,099
  • 7
  • 66
  • 112
  • I'm not sure that forward declaring anything from the `std` namespace is even *allowed*. – Alexandre C. Nov 05 '12 at 21:33
  • @AlexandreC. I forward declare things from std namespace from time to time - never thinks if it is allowed. Well, maybe it is good point to start thinking about it... – PiotrNycz Nov 05 '12 at 21:35
  • 3
    I'm pretty sure that forward declaring anything in namespace `std` is technically be undefined behavior. C++03 §17.4.3.1/1 says "It is undefined for a C++ program to add declarations or definitions to namespace `std` or namespaces within namespace `std` unless otherwise specified." – Adam Rosenfield Nov 05 '12 at 21:40
  • @AdamRosenfield you are right. – PiotrNycz Nov 05 '12 at 21:41
  • I am not sure the quote stands in it's own right. You are not technically *adding* anything to the namespace, you are only instructing the compiler that it is there and will be there after the proper inclusion. On the other hand, in the case of templates, the standard allows the implementation to add any number of template arguments are long as there are defaults, and that makes it impossible to forward declare templates in a portable way. – David Rodríguez - dribeas Nov 05 '12 at 22:40
  • @DavidRodríguez-dribeas The forward declaration is still declaration "The behavior of a C++ program is undefined if it adds declarations [...] to namespace std [...] unless otherwise specified.". Maybe it would be a good point to ask standard committee to add some headers - like with only forward declarations? – PiotrNycz Nov 06 '12 at 09:45
  • @PiotrNycz: I know it is a declaration. The question is whether providing a declaration that is already present in the namespace is **add**-ing a declaration or not. You are not *adding* anything that is not already in the standard. – David Rodríguez - dribeas Nov 06 '12 at 12:15
  • @DavidRodríguez-dribeas I believe it is adding, especially when taking into consideration that actual definition of standard class [template] might differ (some default additional parameter) than those forms described in standard - that is why I believe std committee had also such declarations in their minds - but I am not sure. Maybe this is subject for some new question or re-start discussion in this one: http://stackoverflow.com/questions/10289766/forward-declaration-of-variables-classes-in-std-namespace/10290176#10290176 ? – PiotrNycz Nov 06 '12 at 12:52