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'
}
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 file decl.h with the following:
namespace foo {
...
class A;
...
}
I want to use the whole of declarations from decl.h, except for class A, as I want to have another class, with the same name, declared and defined inside my def.cpp. I'm looking for something that'd allow me to do this:
# include "decl.h"
using namespace foo;
hiding foo::A;
class A {
...
};
Is there anything like that? Or the only way around is to explicitly make each desired member from foo public in my def.cpp?
Just remove using namespace foo;. That's the whole point of namespaces.
You can't hide members of a namespace, and certainly not when using a using namespace ... statement.
The whole point of namespaces is to avoid naming conflicts like you describe.
So, get rid of the using namespace foo; statement, and wrap the second class A in a different namespace, eg:
#include "decl.h"
//using namespace foo;
namespace defcpp {
class A {
...
};
}
Now def.cpp will know about foo::A and defcpp::A. You just have to qualify which one you want to use whenever you need to use an A. For example:
#include "decl.h"
//using namespace foo;
namespace defcpp {
class A {
...
};
}
class B {
defcpp::A a;
...
};
void doSomething()
{
defcpp::A a;
...
}
Suppose I have the following files:
// SomeClass.h
namespace Example
{
class SomeClass
{
...
SomeClass someFunction();
...
};
}
// SomeClass.cpp
Example::SomeClass Example::SomeClass::SomeFunction()
{
...
}
Would there be any consequences to add "using namespace Example;" before the namespace in SomeClass.h to eliminate the need of adding the "Example::" scope operator to things in the Someclass.cpp file? Even if there are no conesequences, would this be considered bad coding practice?
The change would be as follows:
// SomeClass.h
using namespace Example;
namespace Example
{
class SomeClass
{
...
SomeClass someFunction();
...
};
}
// SomeClass.cpp
SomeClass SomeClass::SomeFunction()
{
...
}
No, please don't put using namespace ...; in the global area. You can just do this:
SomeClass.h
// using namespace Example; // never here please
namespace Example
{
using namespace OtherExample; // this is okay (not global)
class SomeClass
{
...
SomeClass someFunction();
...
};
}
SomeClass.cpp
namespace Example // same as in .h
{
using namespace OtherExample; // this is okay (not global)
SomeClass SomeClass::SomeFunction()
{
...
}
}
And I would also suggest with potentially huge namespaces like std:: to never use using namespace std; even within your own namespaces because they simply drag in too many common symbol names.
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.
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;