Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Header files without explicitly writing namespace

Tags:

c++

In a C++ implementation file, I have the option to write something like:

name::space::ClassName::someFunction(int param) {
    // impl
}

instead of

namespace name {
    namespace space {
        ClassName::someFunction(int param) {
            // impl
        }
    }
}

which I find very convenient and more readable. Can this somehow be used in header files, too? Something like this:

class name::space::ClassName {
    // declarations
};

instead of

namespace name {
    namespace space {
        class ClassName {
            // declarations
        };
    }
}

If something like this is possible, then under which conditions? I could imagine, that one would need to forward declare the namespace forward declare the classes within the namespace like this:

namespace name {
    namespace space {
        class ClassName;
    }
}

before being able to use this:

class name::space::ClassName {
    // declarations
};

in a header file.

But somehow I am not able to get this to work 1]. Is it even possible? What bothers me is, that with nested namespaces I have to indent 2 tabs until I can actually declare my class. I would like to use that space in my header files, but I don't want to omit the tabs since this would be against the "everything in curly brackets needs to be tabbed once"-rule (I don't know if there is an actual name for this. If there is, excuse my ignorance, I don't know any :S

1] The problem I faced was not related to the question. The approach actually works, but it has drawbacks (see accepted answer).

like image 651
CharlyDelta Avatar asked Aug 18 '15 13:08

CharlyDelta


People also ask

Does a header file need a namespace?

Code in header files should always use the fully qualified namespace name.

Why should we avoid use of using namespace in header files?

The 'using namespace' directive pulls an entire namespace into not only your header, but also any client code that uses your header. This can provoke ambiguities in client code, or even select the wrong function during overload resolution.

What is difference between header file and namespace?

A header file is a file that is intended to be included by source files. They typically contain declarations of certain classes and functions. A namespace enables code to categorize identifiers. That is, classes, functions, etc.

Can you use using namespace std in a 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.


3 Answers

If you simply don't want the namespace braces enveloping your class definition, you can certainly achieve that by defining the namespace somewhere else with just the class declaration inside. That way, you can come up with something like this:

#ifndef MYCLASS_H
#define MYCLASS_H

namespace ClassNamespace { class MyClass; };

class ClassNamespace::MyClass
{
public:
    MyClass();
    ~MyClass();
    void a();
private:

};

#endif // MYCLASS_H

for the header and this:

#include "MyClass.h"

#include <iostream>

using namespace std;

ClassNamespace::MyClass::MyClass()
{
}

ClassNamespace::MyClass::~MyClass()
{
}

void ClassNamespace::MyClass::a()
{
    cout << "hello";
}

for the implementation.

As you can see, the namespace doesn't enclose the class definition, just its declaration.

As a final note, I personally don't know why you'd want to do this or think it looks nicer to read. I'd personally much rather see the namespace encapsulate the class definition as well as the function definitions. But maybe I've been the odd one all along...

like image 111
nicholaschiasson Avatar answered Sep 28 '22 09:09

nicholaschiasson


No, it doesn't work. One problem is that with

namespace name {
    namespace space {
        class ClassName {
            // declarations
        }
    }
}

you can tell that it is two namespaces and one class.

However, with

class name::space::ClassName {
    // declarations
}

you cannot tell if space is a namespace or a class containing a nested ClassName.

What you can do is save on your tabbing. It is possible to write

namespace name { namespace space {
    class ClassName {
        // declarations
    }
}}
like image 36
Bo Persson Avatar answered Sep 28 '22 08:09

Bo Persson


What you are seeking does not work.

One explanation is that all C++ class and struct types are implicitly associated with their own namespace (which has the same name as the class).

So, given

class name::space::ClassName
{
// declarations
};

the compiler has no way to determine whether name and space are actually namespaces or classes (at best, it must conclude that the construct is ambiguous). So the compiler needs to be explicitly told that name is a namespace, that space is a namespace within name, before being told that ClassName is a class within them.

Hence the need for

namespace name
{
    namespace space
    {
        class ClassName;
    }
}

to forward specify both namespaces and forward declare ClassName within them.

like image 21
Peter Avatar answered Sep 28 '22 09:09

Peter