Correct way to define C++ namespace methods in .cpp file

C++Coding StyleNamespaces

C++ Problem Overview


Probably a duplicate, but not an easy one to search for...

Given a header like:

namespace ns1
{
 class MyClass
 {
  void method();
 };
}

I've see method() defined in several ways in the .cpp file:

Version 1:

namespace ns1
{
 void MyClass::method()
 {
  ...
 }
}

Version 2:

using namespace ns1;

void MyClass::method()
{
 ...
}

Version 3:

void ns1::MyClass::method()
{
 ...
}

Is there a 'right' way to do it? Are any of these 'wrong' in that they don't all mean the same thing?

C++ Solutions


Solution 1 - C++

Version 2 is unclear and not easy to understand because you don't know which namespace MyClass belongs to and it's just illogical (class function not in the same namespace?)

Version 1 is right because it shows that in the namespace, you are defining the function.

Version 3 is right also because you used the :: scope resolution operator to refer to the MyClass::method () in the namespace ns1. I prefer version 3.

See Namespaces (C++). This is the best way to do this.

Solution 2 - C++

5 years later and i thought I'd mention this, which both looks nice and is not evil

using ns1::MyClass;

void MyClass::method()
{
  // ...
}

Solution 3 - C++

I'm using version 4 (below) because it combines most of the advantages of version 1 (terseness of the resoective definition) and version 3 (be maximally explicit). The main disadvantage is that people aren't used to it but since I consider it technically superior to the alternatives I don't mind.

Version 4: use full qualification using namespace aliases:

#include "my-header.hpp"
namespace OI = outer::inner;
void OI::Obj::method() {
    ...
}

In my world I'm frequently using namespace aliases as everything is explicitly qualified - unless it can't (e.g. variable names) or it is a known customization point (e.g. swap() in a function template).

Solution 4 - C++

Googles C++ Style Guide dictates your version 1, without indentation though.

Googles C++ Style Guide for namespaces

Solution 5 - C++

Version 3 makes the association between the class and the namespace very explicit at the expense of more typing. Version 1 avoids this but captures the association with a block. Version 2 tends to hide this so I'd avoid that one.

Solution 6 - C++

I choose Num.3 (a.k.a. the verbose version). It's more typing, but the intent is exact to you and to the compiler. The problem you posted as-is is actually simpler than the real world. In the real world, there are other scopes for definitions, not just class members. Your definitions aren't very complicated with classes only - because their scope is never reopened (unlike namespaces, global scope, etc.).

Num.1 this can fail with scopes other than classes - anything that can be reopened. So, you may declare a new function in a namespace using this approach, or your inlines could wind up being substituted via ODR. You will need this for some definitions (notably, template specializations).

Num.2 This is very fragile, particularly in large codebases - as headers and dependencies shift, your program will fail to compile.

Num.3 This is ideal, but a lot to type - what your intent is to define something. This does exactly that, and the compiler kicks in to make sure you've not made a mistake, a definition is not out of synch with its declaration, etc..

Solution 7 - C++

It turns out it's not only "coding-style matter". Num. 2 leads to linking error when defining and initializing a variable declared extern in header file. Take a look at example in my question. https://stackoverflow.com/questions/24698249/definition-of-constant-within-namespace-in-cpp-file

Solution 8 - C++

All the ways are right, and each one has its advantages and disadvantages.

In the version 1, you have the advantage of not having to write the namespace in front of each function. The disadvantage is that you'll get a boring identation, specially if you have more than one level of namespaces.

In version 2, you make your code cleaner, but if you have more than one namespace being implemented in the CPP, one may access the other one's functions and variables directly, making your namespace useless (for that cpp file).

In version 3, you'll have to type more and your function lines may be bigger than the screen, which is bad for design effects.

There is also another way some people use it. It is similar to the first version, but without the identation problems.

It's like this:

#define OPEN_NS1 namespace ns1 { 
#define CLOSE_NS1 }

OPEN_NS1

void MyClass::method()
{
...
}

CLOSE_NS1

It's up to you to chose which one is better for each situation =]

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMr. BoyView Question on Stackoverflow
Solution 1 - C++GILGAMESHView Answer on Stackoverflow
Solution 2 - C++Puzomor CroatiaView Answer on Stackoverflow
Solution 3 - C++Dietmar KühlView Answer on Stackoverflow
Solution 4 - C++Bjarke Freund-HansenView Answer on Stackoverflow
Solution 5 - C++Paul JoiremanView Answer on Stackoverflow
Solution 6 - C++justinView Answer on Stackoverflow
Solution 7 - C++jakumateView Answer on Stackoverflow
Solution 8 - C++Renan GreinertView Answer on Stackoverflow