given:
namespace root { namespace parent { namespace childa
class hard_to_get_at{};
}}}
namespace root { namespace parent { namespace childb
// how do I refer refer to namespace childb relative to the current namespace ?
..::hard_to_get_at instance_of_childa_class; // psuedo syntax
}}}
Do I need to specify the full path of the namespace? Is there some way around it ?
Next should work :
namespace root{
namespace parent{
namespace childb{
// some function where you want to use class hard_to_get_at
void foo()
{
childa::hard_to_get_at obj;
// do stuff
}
} // namespace childb
} // namespace parent
} // namespace root
I have not tried it, but as far as I remember
childa::hard_to_get_at sibling;
should work from within childb without the need for defining a namespace alias. this is a property of C++ namespace resolution, which is able to move up the hierarchy of nesting to search for namespaces.
You can use a namespace alias in childb
namespace childa = root::parent::childa;
and then
childa::hard_to_get_at sibling;
Related
I have a very basic question about namespace
when should I use "using namespace A::B"?
I know I shouldn't use it in header files, how about .cpp file? In my test.cpp:
namespace A{
namespace B{
namespace C{
A::B::Object obj = ....
}
}
}
the full namespace is A::B::Object as I have right now, Do I actually need A::B? Can I just have Object obj = ....? Should I use using namespace A::B and then have Object obj = ....? I am not sure what this actually means:
namespace A{
namespace B{
namespace C{
.....
}
}
}
I know This means all the contents inside it will have namespace A::B::C, but does it also mean:
using namespace A
using namespace A::B
using namespace A::B::C
implicitly for the contents inside it?
Because obj is not on the root (global) namespace if you write outside its namespace Object the identifier will be not found. So you have a few options:
use fully qualified name:
A::B::C::Object obj = ...
use using declaration:
using namespace A::B::C;
Object obj = ...;
use using declaration:
using A::B::C::Object
Object obj = ...
use namespace alias:
namespace X = A::B::C;
X::Object obj = ...
And basically any combination of above e.g.:
namespace Y = A::B;
Y::C Object obj = ...
using namespace A::B;
C::Object obj = ...
Statements placed in the inner namespaces will be able to reference classes, typedefs, functions, etc from the outer namespaces without explicitly typing them.
namespace A {
class AClass { };
namespace B {
class BClass {
AClass a; // Does not require A::AClass
};
}
}
In addition to using namespace, another way to shorten lengthy compounded namespaces in a .cpp file is to declare a new, shorter namespace:
// MyClass.h
namespace A {
namespace B {
class MyClass {
public:
void f();
};
}
}
// MyClass.cpp
#include "MyClass.h"
namespace AB = ::A::B;
void AB::MyClass::f() {
// impl...
}
(Note that the optional :: at the start of ::A::B explictly tells the compiler that ::A::B is the full path, which is potentially useful if a header had an SomeOtherSpace::A::B namespace and carelessly wrote using namespace SomeOtherSpace.)
I have a class which is not part of any namespace
class A(*) .
And I have another class with same name but part of namespace
class A part of namespace B.
In xyz.cpp, I have the below:
#include "..."
using namespace B;
// some code
A::var; // This A should be part of (*) and not namespace B.
// some code
But since I have conflicting class names, I get errors. Is there a way to get around this?
The using namespace keyword imports all of the names from the specified namespace into the global namespace. Since you already declared a class A in the global namespace, this results in a conflict.
Solution: Don't use using namespace B.
This is effectively what you're doing:
namespace GLOBAL {
class A { ... };
};
namespace B {
class A { ... };
};
using namespace B /* export 'B::A' into 'GLOBAL' resulting in a conflict; */ ;
You may not use
using namespace B;
but use like
B::A::var
instead.
I am having three classes all of them are from different namespaces as shown below:
classA.h
namespace outer
{
namespace inner
{
class ClassA
{
....
};
}
}
classB.h
namespace inner
{
class ClassB
{
...
};
}
classC.h
#include <classB.h>
namespace outer
{
namespace inner2
{
using inner::ClassB; // error here, says outer::inner2::ClassB has not been declared.
class ClassC
{
....
};
}
}
I am stuck at this please help me to solve this issue.
You need
using ::inner::ClassB;
because in namespace outer, you have 2 options for inner
::inner - global namespace
::outer::inner - outer namespace
By default, using inner::ClassB; will try to import ClassB from outer::inner.
i'm having a problem similar to this question, but with one additional depth:
namespace root { namespace parent1 { namespace childa {
class hard_to_get_at{};
}}}
namespace root { namespace parent2 { namespace childb {
// how do I refer refer to namespace childb relative to the current namespace ?
void someFunc()
{
parent1::childa::hard_to_get_at instance; // does not work
}
}}}
when i tried the above, i get an error
error: 'root::parent2::childb::parent1::childa' has not been declared
i don't understand why this does not work, i get the impression that it should. I really don't want to have to put a using declaration inside the someFunc function.
this is happening in g++ 4.5 with c++0x option enabled
You're missing some opening brackets:
namespace root { namespace parent1 { namespace childa { // <--- here
class hard_to_get_at{};
}}}
namespace root { namespace parent2 { namespace childb { // <--- and here
// how do I refer refer to namespace childb relative to the current namespace ?
void someFunc()
{
parent1::childa::hard_to_get_at instance; // does not work
}
}}}
This is one of the reason indentation is important.
Old question but I had the same problem (or same symptom) and at least in my case the issue was quite tricky so posting in case it helps someone.
Basically, if parent1 is a namespace inside of childb anywhere visible from your TU, the lookup will fail. For example:
namespace a { namespace b { namespace c {
class hard_to_get_at {};
}}}
namespace a { namespace d { namespace e {
namespace b {} // May be in any included '.h'
void f() {
b::c::hard_to_get_at foo; // Previous line introduced a::d::e::b which is found before a::b, compiler doesn't backtrack when a::d::e::b::c isn't found.
}
}}}
While I can't see all the code to be sure, my guess is this was in fact OP's problem because the error message "error: 'root::parent2::childb::parent1::childa' has not been declared" suggests that the compiler found a namespace root::parent2::childb::parent1 if it's looking for a childa there.
By the way, this can be replicated with much less nesting, which makes the issue more obvious:
namespace a {
class Foo {};
}
namespace b {
namespace a {}
void f() { a::Foo foo; } // This will fail because 'a' here is '::b::a'
}
This is a rather simple question more or less considering syntax semantics.
I've got a class inside a namespace, which uses a lot of classes out of another namespace:
namespace SomeNamespace
{
class MyClass
{
//...
//These types of namespace uses occur alot around here:
void DoSomething(const anothernamespace::anotherclass &arg);
//...
}
}
This class is of course in its own .hpp file.
I would like to make everything inside the namespace "anothernamespace" available to the MyClass class, however, if I simply put it like this:
namespace SomeNamespace
{
using namespace anothernamespace;
class MyClass
{
//...
//These types of namespace uses occur alot around here:
void DoSomething(const anothernamespace::anotherclass &arg);
//...
}
}
Anyone who does
using namespace SomeNamespace;
Will automatically also use anothernamespace - which is what I want to avoid.
How do I achieve what I want?
The simplest non-perfect-but-helping solution would be to use a namespace alias :
namespace SomeNamespace
{
namespace ans = anothernamespace; // namespace alias
class MyClass
{
//...
//These types of namespace uses occur alot around here:
void DoSomething(const ans::anotherclass &arg);
//...
}
}
Your class users will not "using namespace anothernamespace;", making it more safe, but you still have to use the alias in your class. Not sure it helps, it depends on if you just want to type less or maybe hide a type. Here you put the full namespace in a kind of sub-namespace that don't get into the user's namespaces, but is still available.
Otherwise... there is no way to do exactly what you want. Using namespace don't work inside class declarations.
This does what you want. Both namespaces are accessible to MyClass. using namespace is bad practice in headers though.
namespace SomeNamespace {
namespace other {
using namespace anothernamespace;
class MyClass {
};
}}
namespace SomeNamepace {
typedef other::MyClass MyClass;
}
You really should prefer specifying anothernamespace:: in your class declaration.
You can't. It's just that simple, I'm afraid.