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
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.
I just noticed this. I don't know why this is the case, if i use one element from a namespace i don't want anything else to be accessible without having to use the namespace. For example here, this code is valid:
namespace Test
{
struct Magic
{
int poof;
};
struct Magic2
{
int poof;
};
int Alakazam(const Magic& m)
{
return m.poof;
}
int Alakazam(const Magic2& m)
{
return m.poof;
}
};
using Magic = Test::Magic;
int main()
{
Alakazam(Magic()); // valid
Alakazam(Test::Magic2()); // valid
Test::Alakazam(Magic()); // what i want to only be valid
Test::Alakazam(Test::Magic2()); // this too
}
Any reasoning behind this? Does the spec state that this has to be true?
As suggested by immbis in the comment, this is defined by the standard:
3.4.2: Argument dependent name lookup
When the postfix-expression in a function call is an unqualified-id, other namespaces not considered during the usual
unqualified lookup may be searched, and in those namespaces,
namespace-scope friend function or function template declarations not
otherwise visible may be found. These modifications to the search
depend on the types of the arguments (and for template template
arguments, the namespace of the template argument).
...
If you want to defeat this mecanism, you have to use nested namespace like this, but it's tricky:
namespace Test
{
struct Magic
{
int poof;
};
struct Magic2
{
int poof;
};
namespace Test2 { // use a nested namespace that will not be searched autoamtically
int Alakazam(const Magic& m)
{
return m.poof;
}
int Alakazam(const Magic2& m)
{
return m.poof;
}
}
using namespace Test2; // but give some access to the enclosing namespace
};
Live Demo : Then, your two first calls will not be valid any longer. However, the last call in your example is still possible: you can't prevent the use of fully qualified names outside of the namespace.
I have seen this used in various places. C++ programmers will often use the :: operator right before a global function call.
e.g
::glGenBuffers( 1, &id );
Why is this? Why not just use:
glGenBuffers( 1, &id );
To avoid accidental namespace clashing. For example if you current namespace would have glGenBuffers which does something different from the "good" glGenBuffers with :: you can specify to call the glGenBuffers which is in the global namespace.
The problem is 1) names in inner scopes hide names in outer scopes and 2) there can be ambiguous of function calls when using directive is used.
For example (ambiguity)
#include <algorithm>
using namespace std;
void swap( int &x, int &y )
{
int tmp = x;
x = y;
y = tmp;
}
int main()
{
int x = 5, y = 10;
//swap( x, y ); compiler error: what function to call?
::swap( x, y ); // the user defined function is called
std::swap( x, y ); // the standard function is called.
}
Another example of hidding names
#include <iostream>
void f() { std::cout << "::f()\n"; }
namespace MyNamespace
{
void f() { std::cout << "MyNamespace::f()\n"; }
void g() { f(); } // calls MyNamespace::f()
void h() { ::f(); } // calls ::f()
}
int main()
{
MyNamespace::g();
MyNamespace::h();
}
As you can see here C++ Scope Resolution Operator ::
The :: (scope resolution) operator is used to qualify hidden names so
that you can still use them. You can use the unary scope operator if a
namespace scope or global scope name is hidden by an explicit
declaration of the same name in a block or class.
::glGenBuffers to force choose the method in global namespace
void method()
{
std::cout << "method in global namespace";
}
class Test {
void method()
{
std::cout << "method in Test class";
}
void test()
{
method(); // method in Test class
::method(); //method in global namespace
}
}
Explicitly marking the scope may save you from unexpected matches through using declarations or argument dependent lookup. For example, consider the following:
namespace foo
{
class X {};
void bar(X*, int):
}
// ... much in between ...
foo::X some_object
// ... more in between ...
void bar(X*, long);
int main()
{
bar(&some_object, 42); // calls foo::bar, because it is a better match
::bar(&some_object, 42); // calls ::bar, because it is explicitly told to
}
If you were not aware that there is a bar in namespace foo, or that some_object has a type from namespace foo, the call to foo::bar instead of ::bar may catch you by surprise.
The scope operator (::) is used for accessing the global namespace on 2 occasions mainly:
a) importing a global method / variable / typedef (from global namespace) into a namespace:
int fun()
{
return 1;
}
namespace x
{
using ::fun;
// you cannot do `using fun`, as using requires a namespace after
// in this case, we are `using` the global namespace
}
int main()
{
std::cout << fun() + x::fun(); // prints 2
}
Edit: This is done by some STL implementations, for example: std::size_t:
typedef unsigned int size_t;
namespace std
{
using ::size_t;
}
size_t x = 1;
std::size_t y = 2;
b) To avoid clashing:
# include <algorithm>
using namespace std;
template<class T> inline
void swap(T &left, T &right)
{
T tmp = left;
left = right;
right = tmp;
}
int main()
{
int a = 1, b = 2;
// swap(a, b) - error: which 'swap'?
std::swap(a, b); // the one in <algorithm>
::swap(a, b); // the one i defined
}
Note: using namespace std; is not a reccomended practise.
Edit
MSVC compiler provides the _CSTD macro (#define _CSTD ::), so that you can use using _CSTD fun;, e.t.c instead if you prefer.
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