2

Let's say that in your own project you have your own namespace. Then how are you supposed to use "MyNamespace" in the header / CPP files?

This works:

namespace MyNamespace{

class MyClass{

    MyClass(MyNamespace::MyClass&) {}
    MyClass(MyNamespace::MyOtherClass&) {}


    MyNamespace::MyClass& operator=(const MyNamespace::MyClass&) {return *this;}

};

inline void someFunc(MyNamespace::MyClass& obj){};

}

This works too:

namespace MyNamespace{

class MyClass{

    MyClass(MyClass&) {}
    MyClass(MyOtherClass&) {}

    MyClass& operator=(const MyClass&) {return *this;}

};

inline void someFunc(MyClass& obj){};

}

If I don't write "MyNamespace::" at all then it's like I'm not even using namespaces, especially with this line if "MyOtherClass" is from a different file:

MyClass(MyNamespace::MyOtherClass&) {}

But then this certainly looks too much:

MyNamespace::MyClass& operator=(const MyNamespace::MyClass&) {return *this;}

In the CPP file, am I supposed to use "using namespace MyNamespace;" or "namespace MyNamespace{"?

2
  • 1
    Are you asking about which coding style you should use? Commented Apr 12, 2018 at 8:01
  • @StoryTeller I never used namespaces until now apart from "std::" so I don't know if I got the syntax right or how am I supposed to use them for my own project Commented Apr 12, 2018 at 8:05

3 Answers 3

4

Name lookup starts at the immediately enclosing scope and propagates to progressively higher scopes until it finds something. This means that when you're inside the definition of namespace MyNamespace (that is, between the { and } of namespace MyNamespace { /*...*/ }), all names defined in MyNamespace can be used unqualified and name lookup will find them correctly. This is also the most common way code is normally written.

So in your case, the second code sample (the one titled "This works too") is what one would normally expect C++ code to look like. Namespaces are supposed to help maintain name uniqueness, not get in the way.

Note that files (as you wrote "from a different file") have nothing to do with this, really. Inside a namespace, you'd refer to members of that namespace without qualification. Outside a namespace, you'd normally use qualification to access the namespace's members.

Exceptions

There are times when you may want to qualify a name explicilty even when you're in its namespace. This happens when you want to prevent Argument-Dependent Lookup: when a function is called using an unqualified name, the function's name is also looked up in namespaces associated with the types of the arguments provided(1). If you prevent this and ensure the function from your namespace is called, qualify its name. Note that this mainly applies within templates, where the namespaces associated with template parameters are not known when writing the code.

You may also be forced to use qualification if you encounter an ambiguity. This can happen if you indiscriminately "pollute" your namespace/scope with using directives and/or using declarations. The better solution there is to avoid using such constructs for "less typing", and only employ them when you actually want their full semantics.


(1)This allows things like std::operator << to be found without need for qualification when one of the arguments is e.g. std::cout.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! Is this the same for the CPP file? Do people normally write the "This works too" type of syntax? And do they write "namespace MyNamespace" in the CPP too, or "using namespace MyNamespace"? I mean since you don't normally include the CPP file anywhere does the content need to be in "namespace MyNamespace"?
@AdyAdy It's best to use the same rules in .cpp files as you use for .h files; that is, open the namespace and define all its contents inside its scope. using namespace MyNamespace; can work when defining class member functions, but does not work when defining namespace-scope functions (it introduces unrelated definitions in the global namespace).
0

Defining namespaces

namespace myNamespace
{
  int a, b;
}

These variables can be accessed from within their namespace normally, with their identifier (either a or b), but if accessed from outside the myNamespace namespace they have to be properly qualified with the scope operator ::. This is why your second example is working fine, as you are using MyClass within the namespace that defines it.

Usage

myNamespace::a
myNamespace::b 

Using using

#include <iostream>
using namespace std;

namespace first
{
  int x = 5;
  int y = 10;
}

namespace second
{
  double x = 3.1416;
  double y = 2.7183;
}

int main () {
  using first::x;
  using second::y;
  cout << x << '\n';
  cout << y << '\n';
  cout << first::y << '\n';
  cout << second::x << '\n';
  return 0;
}

or

#include <iostream>
using namespace std;

namespace first
{
  int x = 5;
  int y = 10;
}

namespace second
{
  double x = 3.1416;
  double y = 2.7183;
}

int main () {
  using namespace first;
  cout << x << '\n';
  cout << y << '\n';
  cout << second::x << '\n';
  cout << second::y << '\n';
  return 0;
}

Comments

0

Both versions produce the same executable. While inside the block namespace MyNamespace{}, everything that would be normally accessible if it weren't in a namespace but that has been declared within that same namespace MyNamespace is accessible without having to use the :: operator. You can still use it if you want, though. The same as you can write this->myDataMember when accessing the data member myDataMember of a class from within the class, but you don't have to.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.