The correct way to define C ++ namespace methods in a .cpp file

Perhaps a duplicate, but not a simple search ...

Given a headline like:

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

I see method() defined in several ways in a .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 this? Are any of these “wrong” ones that they do not all mean the same thing?

+73
c ++ coding-style namespaces
Dec 30 '11 at 16:37
source share
8 answers

Version 2 is obscure and incomprehensible because you do not know which namespace MyClass belongs to, and this is simply illogical (the class function is not in the same namespace?)

Version 1 is correct because it shows that you define a function in the namespace.

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

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

+34
Dec 30 '11 at 16:48
source share

I use version 4 (see below) because it combines most of the advantages of version 1 (multiplicity of the re-efficient definition) and version 3 (as explicit as possible). The main disadvantage is that people are not used to it, but since I consider it technically superior to alternatives, I am not opposed.

Version 4: Use full qualifications using namespace aliases:

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

In my world, I often use namespace aliases, since everything is explicitly qualified - if it cannot (for example, variable names) or it is a known setting point (for example, swap () in a function template).

+12
Dec 30 '11 at 17:54
source share

5 years later, and I thought I mentioned it, which both looks beautiful and not evil.

 using ns1::MyClass; void MyClass::method() { // ... } 
+12
Apr 18 '16 at 19:08
source share

Version 3 makes the relationship between class and namespace very explicit due to more typing. Version 1 avoids this, but fixes communication with the block. Version 2 tends to hide this, so I would avoid this.

+4
Dec 30 '11 at 16:49
source share

It turns out that this is not only a “coding style subject”. Num. 2 leads to a binding error when defining and initializing the declared extern variable in the header file. Take a look at an example in my question. Defining a constant in a namespace in a cpp file

+3
Jul 15 '14 at 8:17
source share

All methods are correct, and each of them has its advantages and disadvantages.

In version 1, you have the advantage of not having to write a namespace before each function. The downside is that you get boring identification, especially if you have more than one level of namespace.

In version 2, you make your code cleaner, but if more than one namespace is implemented in CPP, you can directly access other functions and variables, which makes your namespace useless (for this cpp file).

In version 3, you will need to enter more, and your function lines may be larger than the screen, which is bad for design effects.

There is another way to use it by some people. This is similar to the first version, but without identification problems.

This is true:

 #define OPEN_NS1 namespace ns1 { #define CLOSE_NS1 } OPEN_NS1 void MyClass::method() { ... } CLOSE_NS1 

You decide which one is best for each situation =]

+1
Dec 30 '11 at 16:51
source share

I choose Num. 3 (aka verbose version). This prints more, but the intent is for you and the compiler. The problem that you posted as it is is actually simpler than the real world. In the real world, there are other areas of definition, not just class members. Your definitions are not very complicated just for classes - because their scope never opens (unlike namespaces, global scope, etc.).

Num. 1 this may fail with areas other than classes - anything that can be reopened. That way, you can declare a new function in the namespace using this approach, or your inline strings can be replaced via ODR. You will need this for some definitions (in particular, specialized templates).

Num.2 This is very fragile, especially in large codebases - when shifting headers and dependencies your program will not be able to compile.

Num.3 This is ideal, but of many types - what you intend to define. This does just that, and the compiler starts to make sure that you haven't made a mistake, the definition does not synchronize with its declaration, etc.

+1
Dec 30 2018-11-12T00:
source share

The Google C ++ Googles Style Guide defines your version 1 without indentation.

Googles C ++ Style Guide for namespaces

+1
Jan 18 '17 at 10:29 on
source share



All Articles