Namespace alias scoping issues - c++

I have a header file in which I wish to use a namespace alias while defining a class. However I don't want to expose this alias to anything that includes the header file.
// foo.h
namespace qux = boost::std::bar::baz::qux; // ! exposed to the world
class foo
{
// can't put a namespace alias here
// stuff using qux::
};
How can I alias a namespace for a class declaration without it leaking out everywhere?

namespace MyClassSpace
{
namespace qux = boost::std::bar::baz::qux;
class foo
{
// use qux::
};
}
using MyClassSpace::foo; // lift 'foo' into the enclosing namespace
This is also how most Boost libraries do it, put all their stuff in a seperate namespace and lift the important identifiers into the boost namespace.

Related

Namespace qualified names INSIDE a user namespace

In C++, if I have
namespace myNamespace {
boost::whatever();
}
will the compiler look for whatever() in the boost namespace or in myNamespace::boost?
The question is not about whether it will look for boost::whatever, but where it will find boost itself.
If you have a nested namespace definition with the name boost, it will hide the global boost namespace at its point of declaration. The global boost namespace will be visible up until the point where myNamespace::boost is declared (§3.3.2/2).
[ Note: a name from an outer scope remains visible up to the point of declaration of the name that hides it. [ Example:
const int i = 2;
{ int i[i]; }
declares a block-scope array of two integers. — end example ] — end note ]
So if you're calling boost::whatever() before the nested name myNamespace::boost is created, it will look for the global boost namespace. You can qualify the name with ::boost if you always want it to find boost in the global namespace.
First of all I think you mean this:
namespace myNamespace {
using boost::whatever; // NOT boost::whatever();
}
Remember that C++ namespaces are mainly to avoid naming clashes not a design mechanism, which means when you are using a method of other namespaces in another one, you just call the original one and there is no copy in new namespace scope. So, when you call myNamespace::whatever(), compiler would choose boost::whatever() not myNamespace::boost::whatever() because there is no boost namespace declared inside myNamespace.
For more details on namespaces you could see:
http://en.cppreference.com/w/cpp/language/namespace
Assuming you want to call a function using some qualification, you may end up using a local namespace rather than a global namespace:
#include <iostream>
namespace A { void f() { std::cout << "::A::f()\n"; } }
namespace B {
namespace A { void f() { std::cout << "::B::A::f()\n"; } }
void g() { A::f(); }
void h() { ::A::f(); }
}
int main() {
B::g();
B::h();
}
If you want to make sure you are picking up a specific namespace you'll need to use absolute qualification as in ::A::f().

What is the difference between "using" namespace and declaring namespace?

Could somebody tell me what is the difference between
using namespace android;
....
and
namespace android {
....
}
I found that almost all .cpp files in Android source code use the second one.
Also, If I want to include some files that use the type of second one in my own project, do I need to use namespace android{...} too?
Because if I do not, compiler would report error when I call methods of included files. Or do I need to add any prefix before method call?
namespace android {
extern int i; // declare here but define somewhere
void foo ();
}
-- is used for scoping variables and functions inside a particular name. While using/calling those variables/functions, use scope resolution operator ::. e.g.
int main ()
{
android::foo();
}
There is no restriction for putting all namespace declarations in a single body instance. Multiple namespace android bodies spread across several files, is possible and also recommended sometimes. e.g.
// x.cpp
namespace android {
void somefunc_1 ();
}
// y.cpp
namespace android {
void somefunc_2 ();
}
Now, sometimes you may find using :: operator inconvenient if used frequently, which makes the names unnecessarily longer. At that time using namespace directive can be used.
This using directive can be used in function scope / namespace scope / global scope; But not allowed in class scope: Why "using namespace X;" is not allowed inside class/struct level?).
int main ()
{
using namespace android;
foo(); // ok
}
void bar ()
{
foo(); // error! 'foo' is not visible; must access as 'android::foo()'
}
BTW, Had using namespace android; declared globally (i.e. above main()), then foo() can be accessed without :: in Bar() also.
My answer is probably only helpful if you are more experienced with Java. I'm guessing since you are doing android stuff that this is the case.
The following means that you are declaring a class called MyClass in the namespace android. The qualified name of the class would be android::MyClass.
namespace android {
class MyClass {...};
}
It can be thought of similarly to the Java code:
package android;
public class MyClass {...}
The following means that you can use classes, functions etc. defined in the android namespace without having to use their qualified name (assuming they have been included).
using namespace android;
This
#include <path/to/MyClass.h>
using namespace android;
can be thought of similarly to the Java code:
import android.MyClass;

C++ namespace alias in entire class scope

I expected to be able to use a namespace alias in a class declaration but get a compiler syntax error.
struct MyClass
{
namespace abc = a_big_namespace;
void fn() {
abc::test();
}
};
The only way I can get it to work is to put the alias in every function.
void fn() {
namespace abc = a_big_namespace;
abc::test();
}
Additionally I would like to be able to use the alias for function parameters. I haven't found a work-around for that.
void fn(abc::testType tt) {
abc::test(tt);
}
Is there a way to do what I want?
EDIT: my solution
I found that I didn't need unnamed namespace for my particular problem and can simply do this:
namespace myspace
{
namespace abc = a_big_namespace;
struct MyClass
{
void fn(abc::testType tt) {
abc::test(tt);
}
};
}
To switch to the other library, which is what my alias namespace refers to I just change the alias. This method even allows me to have the same class in a single file twice, each time refering to a different library.
Thanks for all your help.
Namespace alias in the class definition is illegal, as specified by the language specification.
Its allowed in only in namespace scope or function scope.
You can make alias at namespace scope. But that will be make permanent alias which can be used from other files as well. But the solution is simple : you can use unnamed namespace to prevent alias (and therefore all symbols from the big namespace) from being visible from other files. This is how it can be done:
//MyFile.cpp
namespace myspace
{
namespace //this is unnamed namespace
{
namespace abc = a_big_namespace;
}
struct MyClass
{
void fn()
{
abc::test(); //don't worry, this will work!
}
};
}
//OtherFile.cpp
myspace::abc::test(); //error - that means, prevention worked.
The alias is not visible from other files. When compiling OtherFile.cpp, GCC (4.5.0) says,
'myspace::abc' has not been declared
That proves the alias abc is visible only in MyFile.cpp. Thanks to unnamed namespace.
Demo : http://www.ideone.com/2zyNI (though it doesn't demonstrate OtherFile concept. I cannot have more than one file at ideone.com)
The scope of a namespace alias is a code block.
So you can put it in any code block.
BUT, you can't put it inside a class, because that will mean it's a member of the class.
A namespace alias can't be a member.
More about namespace aliases:
What is the scope of a namespace alias in C++?
Namespaces
It works if you declare the alias outside of the struct.
You can of course also put the alias outside the class:
namespace abc = a_big_namespace;
struct MyClass {
void fn()
{ abc::test(); }
};

Is it possible to avoid C++ compiler error (C2757) where 2 different header files contain same symbol for namespace & class?

I am facing a problem when implementing some new code to an existing library. This library already references a class with a name say 'foo'. The same name is used as a namespace in the other header file which has to be included to implement the new functionality. Since both the header files are a part of legacy code libraries I cannot amend them. So here I am looking for any way so as to avoid the Compiler Error (C2757: a symbol with this name already exists and therefore this name cannot be used as a namespace name). I am not sure whether it is possible or not. Hence, Any help shall be appreciated. Thanks
For clarity here is the sample code illustration for the issue:
HeaderA.h
class foo
{}
HeaderB.h
namespace foo
{
class ABC{}
}
HeaderC.h
#include <HeaderA.h>
#include <HeaderB.h>
using namespace foo;
class Toimplement{
ABC a; //Throws Error C2757
}
You can try the following workaround:
namespace bar {
#include "HeaderA.h"
}
#include "HeaderB.h"
...
bar::foo fooObject;
foo::ABC abcObject;
Include one of header file in new namespace.
namespace headerb {
#include <HeaderB.h>
}
...
...
headerb::ABC a1;
ABC b2;
In your example, the simplest approach is to not include HeaderA.h in HeaderC.h. The class foo isn't needed in Toimplement.
so let's assume you need the visibility of both files, and you want to link to the symbols included by HeaderA:
// header a
class FOO {};
// followed by a file with your declarations/disambiguators
typedef FOO wwlib_FOO;
// header b
namespace FOO {class ABC {};}
// followed by a file with your declarations/disambiguators
namespace vvlib_FOO = FOO;
// and finally usage
using namespace FOO; // note: using `using` is a good way to introduce complications like this one
void fn() {
class FOO t;
wwlib_FOO t2(t);
vvlib_FOO::ABC abc;
...
the namespace trick won't work, apart from very very simple cases (unless it's entirely templates or inlines, which is very unusual). you'll just end up with duplicated code, classes that you can't pass around, and missing references at link-time.

C++ namespaces and defining classes in separate files

I want to make a namespace that will contain several classes as part of a "package".
Do I have to declare all of the classes within the namespace?
For example, if I have a "2dEngine.h" which defines the 2dEngine namespace, do I have to declare all of the individual classes within that header file? Or can I still separate them into separate header (.h) files and have them be part of the namespace?
Pseudo example:
TwoEngine.h
namespace TwoEngine
{
class Canvas
{
// Define all of Canvas here
};
class Primitive
{
// Define all of Primitive here
};
}
Instead of doing that, I want to have Canvas and Primitive be their own .h files and just somehow state that they are part of that namespace.
Sorry, I'm still pretty new to this.
Yes, you can split the namespace into multiple blocks (and hence files). Your classes will belong to the same namespace as long as they are declared in the namespace block with the same name.
// Canvas.h
namespace TwoEngine
{
class Canvas
{
// Define all of Canvas here
};
}
// Primitive.h
namespace TwoEngine
{
class Primitive
{
// Define all of Primitive here
};
}
Namespaces can be discontiguous. You can take advantage of this by keeping relevant classes in your 2DEngine.h which probably is going to be used by client code and will be shipped as part of your library.
Anything else, that is not to be revealed to the outside world can still be put in the same namespace but in a separate header file (which is not shipped).
Header H1.h (part of the library interface to the external world)
namespace TwoEngine
{
class Canvas
{
// Define all of Canvas here
};
}
Header H2.h (not part of the library interface to the external world)
#include "H1.h"
namespace TwoEngine // reopen the namespace and extend it
{
class Primitive
{
// Define all of Primitive here
};
}
Yes just use the name space directive inside the implementation files also.