What is a "namespace alias" in C++? How is it used?
A namespace alias is a convenient way of referring to a long namespace name by a different, shorter name.
As an example, say you wanted to use the numeric vectors from Boost's uBLAS without a using namespace directive. Stating the full namespace every time is cumbersome:
boost::numeric::ublas::vector<double> v;
Instead, you can define an alias for boost::numeric::ublas -- say we want to abbreviate this to just ublas:
namespace ublas = boost::numeric::ublas;
ublas::vector<double> v;
Quite simply, the #define won't work.
namespace Mine { class MyClass { public: int i; }; }
namespace His = Mine;
namespace Yours { class Mine: public His::MyClass { void f() { i = 1; } }; }
Compiles fine. Lets you work around namespace/class name collisions.
namespace Nope { class Oops { public: int j; }; }
#define Hmm Nope
namespace Drat { class Nope: public Hmm::Oops { void f () { j = 1; } }; }
On the last line, "Hmm:Oops" is a compile error. The pre-processor changes it to Nope::Oops, but Nope is already a class name.
More on this topic http://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Core-C-/Stephan-T-Lavavej-Core-C-1-of-n
It is all about choosing an alias for a looong namespace name, such as:
namespace SHORT = NamespaceFirst::NameSpaceNested::Meow
Then later, you can typedef
typedef SHORT::mytype
instead of
typedef NamespaceFirst::NameSpaceNested::Meow::mytype
This syntax only works for namespaces, cannot include classes, types after the namespace NAME =
Also note that namespace aliases and using directives are resolved at compile time, not run time. (More specifically, they're both tools used to tell the compiler where else to look when resolving names, if it can't find a particular symbol in the current scope or any of its parent scopes.) For example, neither of these will compile:
namespace A {
int foo;
namespace AA {
int bar;
} // namespace AA
namespace AB {
int bar;
} // namespace AB
} // namespace A
namespace B {
int foo;
namespace BA {
int bar;
} // namespace BA
namespace BB {
int bar;
} // namespace BB
} // namespace B
bool nsChooser1, nsChooser2;
// ...
// This doesn't work.
namespace C = (nsChooser1 ? A : B);
C::foo = 3;
// Neither does this.
// (Nor would it be advisable even if it does work, as compound if-else blocks without braces are easy to inadvertently break.)
if (nsChooser1)
if (nsChooser2)
using namespace A::AA;
else
using namespace A::AB;
else
if (nsChooser2)
using namespace B::BA;
else
using namespace B::BB;
Now, a curious mind may have noticed that constexpr variables are also used at compile time, and wonder whether they can be used in conjunction with either an alias or a directive. To my knowledge, they cannot, although I may be wrong about this. If you need to work with identically-named variables in different namespaces, and choose between them dynamically, you would have to use references or pointers.
// Using the above namespaces...
int& foo = (nsChooser1 ? A::foo : B::foo);
int* bar;
if (nsChooser1) {
if (nsChooser2) {
bar = &A::AA::bar;
} else {
bar = &A::AB::bar;
}
} else {
if (nsChooser2) {
bar = &B::BA::bar;
} else {
bar = &B::BB::bar;
}
}
The usefulness of the above may be limited, but it should serve the purpose.
(My apologies for any typoes I may have missed in the above.)
Namespace is used to prevent name conflicts.
For example:
namespace foo {
class bar {
//define it
};
}
namespace baz {
class bar {
// define it
};
}
You now have two classes name bar, that are completely different and separate thanks to the namespacing.
The "using namespace" you show is so that you don't have to specify the namespace to use classes within that namespace. ie std::string becomes string.
my resource: https://www.quora.com/What-is-namespace-in-C++-1
Related
If there are two namespaces named Foo and Bar and there is a namespace named Foo inside Bar. If I refer to a variable Foo::i from inside Bar will it search for i in both Foo and Bar::Foo. If not, is it possible to make the compiler search in both namespaces when i doesn't exist in Bar::Foo?
More concrentely in the below example, I am trying to refer variable i from namespace a in b without puting extra ::. I know putting :: works, I am trying to see if there is any other way to resolve this.
#include <iostream>
#include <string>
namespace a {
int i = 1;
}
namespace b {
namespace a {
}
namespace c {
int j = a::i; // Doesn't work, need to use ::a::i;
}
}
int main()
{
std::cout << b::c::j << "\n";
}
If you can change b::a, then you can indeed make certain declarations available in b::a from ::a as fallbacks:
namespace a {
int i = 1;
int j = 2;
}
namespace b {
namespace a {
namespace detail {
using ::a::i; // Selectively bring declarations from ::a here
}
using namespace detail; // Make the names in detail available for lookup (but not as declarations).
//int i = 2;
}
namespace c {
int j = a::i; // Uses ::a::i
// int k = a::j; // ERROR! We didn't bring ::a::j into b::a at all
}
}
Here it is live.
Un-commenting the declaration of b::a::i will change the output. Since a proper declaration takes precedence over names brought in by a namespace using directive.
You could explicitly have a using declaration in the inner namespace for variables that it wants to use from the outer one.
i.e. for your example,
namespace a {
int i = 1;
}
namespace b {
namespace a {
using ::a::i; //inner one does not define its own
int i2 = 2; //inner one creates its own variable
}
namespace c {
int j = a::i; // Doesn't work, need to use ::a::i;
}
}
See:
https://en.cppreference.com/w/cpp/language/namespace#Using-declarations
I am trying to find a way to group the main types and constants used by my project into a namespace, and then I'd like to import them in all my classes with "using namespace". I can't figure out why this piece of code doesn't compile, g++ error says:
expected nested-name-specifier before 'namespace'
What options do I have to have all my types and constants grouped together? I tried making Traits a struct and then using inheritance but this gives problems with templates, another way is writing in all classes something like:
using scalar_t = Traits::scalar_t;
Thanks for any tip.
#include <iostream>
namespace Traits {
constexpr int N = 3;
using scalar_t = double;
};
struct Entity {
using namespace Traits; // problems here
scalar_t foo() const;
int n = N;
};
scalar_t Entity::foo() const { return N; } // problems here
int main()
{
Entity e;
e.foo();
return 0;
}
The language doesn't actually allow you to import a namespace at class scope. You can solve this by adding another level of indirection, viz. wrapping your class in a namespace, where you can of course import other namespaces.
namespace Indirection
{
using namespace Traits; // ok at namespace scope
// now everything from Traits is avaliable
struct Entity
{
scalar_t foo() const; // scalar_t is visible, yay!
int n = N;
};
scalar_t Entity::foo() const { return N; } // also ok, since in same namespace
}
Of course, you don't want to ever have to mention the Indirection namespace again, so you can just lift the Entity out of that namespace.
using Indirection::Entity;
and now it's as if Indirection never existed at all.
Here's a demo.
is it possible to set a namespace alias in an if-statement and use it afterwards?
I tried it with the following code:
const int dim = 2;
//default namespace
namespace poissonProblem = poissonProblem3D;
//trying to set the necessary namespace
if(dim == 1){
namespace poissonProblem = poissonProblem1D;
}
else if (dim == 2){
namespace poissonProblem = poissonProblem2D;
}
else if (dim == 3){
namespace poissonProblem = poissonProblem3D;
}
But when I try to use a function such as poissonProblem::eval() afterwards, it's still the function poissonProblem3D::eval() which is used.
Have you any ideas why, or suggestions for other ways of implementation/work-arounds?
I don't want to implement the code for every dimension because it's almost the same despite the used namespace.
Thanks,
Justus
One option is to use a trait class template:
template <int> struct Feature;
template <> struct Feature<1> {
static void eval() { problem1D::eval(); }
// ... other functions
};
template <> struct Feature<2> {
static void eval() { problem2D::eval(); }
// ... other functions
};
Usage:
const int dim = 2;
int main() {
Feature<dim>::eval();
}
The namespace alias that you define is meant for telling the compiler which namespace to use when looking up for symbols at compile time.
What's the problem ?
So when you write
if(dim == 1) {
namespace poissonProblem = poissonProblem1D;
}
you just define a namespace alias for the if-bloc. It's forgotten as soon as you leave the block.
You should not think that the namespace alias is something dynamic that could be changed in the sequence of your program.
Why is it so ?
Imagine:
namespace poissonProblem1D {
class X {
public:
X(int c) {} // constructor only with int parameter
virtual ~X() {} // virtual destructor
}; // only a constructor with int is allowed
}
namespace poissonProblem2D {
class X {
public:
X() {} // only constructor without argument
~X() {} // non virtual destructor
}; // only a constructor with int is allowed
}
Suppose now that you could redefine the namespace in the flow of execution as you desired, and that the execution of if-blocks could alter the the namespace alias. How could the compiler then compile the statement:
poissonProblem::X x(2);
We have two types poissonProblem1D::X and poissonProblem2D::X, but the compiler wouldn't know at compile time which one to use, which are the valid or invalid parameters and how to generate code for the destruction of the object x.
C++ has strong compile-time type checking which makes dynamic namespace alias impossible.
Edit: How to solve it ?
It depends on the context. Kerek already showed a template based approach.
Another approach is to use conditional compilation. This can prove useful for configuring the the namespace at compilation time (for example choose to use a boost or a std version of a class such as regex).
#define dim 2
#if dim==2
namespace poissonProblem = poissonProblem2D;
#elif dim==1
namespace poissonProblem = poissonProblem1D;
#elif dim==3
namespace poissonProblem = poissonProblem3D;
#endif
Consider the following snippet:
void Foo() // 1
{
}
namespace
{
void Foo() // 2
{
}
}
int main()
{
Foo(); // Ambiguous.
::Foo(); // Calls the Foo in the global namespace (Foo #1).
// I'm trying to call the `Foo` that's defined in the anonymous namespace (Foo #2).
}
How can I refer to something inside an anonymous namespace in this case?
You can't. The standard contains the following section (§7.3.1.1, C++03):
An unnamed-namespace-definition behaves as if it were replaced by
namespace unique { /* empty body */ }
using namespace unique;
namespace unique { namespace-body }
where all occurrences of unique in a
translation unit are replaced by the
same identifier and this identifier
differs from all other identifiers in the entire program.
Thus you have no way to refer to that unique name.
You could however technically use something like the following instead:
int i;
namespace helper {
namespace {
int i;
int j;
}
}
using namespace helper;
void f() {
j++; // works
i++; // still ambigous
::i++; // access to global namespace
helper::i++; // access to unnamed namespace
}
While Georg gives standard-complient, correct, right, and respectable answer, I'd like to offer my hacky one - use another namespace within the anonymous namespace:
#include <iostream>
using namespace std;
namespace
{
namespace inner
{
int cout = 42;
}
}
int main()
{
cout << inner::cout << endl;
return 0;
}
The only solution I can think of that doesn't modify the existing namespace arrangement is to delegate main to a function in the anonymous namespace. (main itself is required to be a global function (§3.6.1/1), so it cannot be in an anonymous namespace.)
void Foo() // 1
{
}
namespace
{
void Foo() // 2
{
}
}
namespace { // re-open same anonymous namespace
int do_main()
{
Foo(); // Calls local, anonymous namespace (Foo #2).
::Foo(); // Calls the Foo in the global namespace (Foo #1).
return 0; // return not optional
}
}
int main() {
return do_main();
}
The only real way is to put the code you want to access that namespace within the namespace itself. There's no way to resolve to the unnamed namespace otherwise, since it has no identifier you can give it to solve the ambiguous resolution problem.
If your code is inside the namespace{} block itself, the local name gets priority over the global one, so a Foo() will call the Foo() within your namespace, and a ::Foo() will call the namespace at global scope.
Just rename the local namespace function.
I've got a namespace with a ton of symbols I use, but I want to overwrite one of them:
external_library.h
namespace LottaStuff
{
class LotsOfClasses {};
class OneMoreClass {};
};
my_file.h
using namespace LottaStuff;
namespace MyCustomizations
{
class OneMoreClass {};
};
using MyCustomizations::OneMoreClass;
my_file.cpp
int main()
{
OneMoreClass foo; // error: reference to 'OneMoreClass' is ambiguous
return 0;
}
How do I get resolve the 'ambiguous' error without resorting to replacing 'using namespace LottaStuff' with a thousand individual "using xxx;" statements?
Edit: Also, say I can't edit my_file.cpp, only my_file.h. So, replacing OneMoreClass with MyCustomizations::OneMoreClass everywhere as suggested below wouldn't be possible.
The entire point of namespaces is defeated when you say "using namespace".
So take it out and use namespaces. If you want a using directive, put it within main:
int main()
{
using myCustomizations::OneMoreClass;
// OneMoreClass unambiguously refers
// to the myCustomizations variant
}
Understand what using directives do. What you have is essentially this:
namespace foo
{
struct baz{};
}
namespace bar
{
struct baz{};
}
using namespace foo; // take *everything* in foo and make it usable in this scope
using bar::baz; // take baz from bar and make it usable in this scope
int main()
{
baz x; // no baz in this scope, check global... oh crap!
}
One or the other will work, as well as placing one within the scope for main. If you find a namespace truly tedious to type, make an alias:
namespace ez = manthisisacrappilynamednamespace;
ez::...
But never use using namespace in a header, and probably never in global scope. It's fine in local scopes.
You should explicitly specify which OneMoreClass you want:
int main()
{
myCustomizations::OneMoreClass foo;
}