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;
...
}
Related
Is it possible to use class name which declare in namespace without namespace?
I tried like this:
//MyClass.h
namespace MyNamespace {
class MyClass;
}
class MyNamespace::MyClass {
public:
/* ... */
}
//MyOtherClass.cpp
#include "MyClass.h"
using namespace MyNamespace;
void MyOtherClass::MyFunction() {
MyClass *myClass = new MyClass;
}
But it doesn't work.
Complier says "MyClass is ambiguous."
I guess this code would work :
//MyOtherClass.cpp
#include "MyClass.h"
using namespace MyNamespace;
void MyOtherClass::MyFunction() {
MyNamespace::MyClass *myClass = new MyClass;
}
But it is uncomfortable for me.
I wanna use 'MyClass' without "MyNamespace::".
Is it possible?
Thanks for your help.
I got answer : It is not possible.
C++ classes have own default namespace. If I declare MyNamespace, then there is two namespaces associated with MyClass. If I use MyClass without choosing what namespace I want to use, Compiler feel ambiguous what namespace I really wanted to use. So it would tell me "MyClassis ambiguous."
if the below code is all in the same .h file (you did not really clarify)
//MyClass.h
namespace MyNamespace {
class MyClass;
}
class MyNamespace::MyClass {
public:
/* ... */
}
Then what you are doing a forward declaration of MyNamespace::MyClass in the first part.
You should have something like this in MyClass.h
namespace MyNamespace {
class MyClass
{
public:
// constructor, methods,...
}; // end of class declaration
} // end of namespace
and the associated definition in MyClass.cpp
Not sure if this is possible, but I have two classes of the same name in different levels of a nested namespace and I'd like to make the more shallow class a friend of the deeper class. Example:
In File1.h:
namespace A
{
class Foo
{
//stuff
};
}
In File2.h:
namespace A
{
namespace B
{
class Foo
{
friend class A::Foo; //Visual Studio says "Error: 'Foo' is not a member of 'A'"
};
}
}
Is this possible? If so, what is the proper syntax?
This code compiles ok when placed in one file (except that a ; is necessary after A::B::Foo class): IdeOne example.
So, the issue is in the code not included in the question text. Probably #include "File1.h" was forgotten in File2.h.
If you want to avoid including large header files into others, you need to at least forward declare your classes before using them:
namespace A
{
class Foo;
namespace B
{
class Foo
{
friend class A::Foo;
}
}
}
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.
I want to use an 3rd party library without using its header file. My code resides in its own namespace, therefore I can't use conventional forward declaration as I don't want to pollute the global namespace. Currently I have something like that:
3rd-party-library.h----
typedef struct {...} LibData;
void lib_func (LibData *);
my-source.h-----
namespace foo {
/*forward declaration of LibData*/
class Abcd {
public:
void ghj();
private:
Libdata *data_;
};
}//namespace foo
my-source.cpp-----
#include "my-source.h"
#include <3rd-party-library.h>
namespace foo {
typedef ::LibData LibData;
void Abcd::ghj() {
//do smth with data_
}
}//namespace foo
Is it possible to forward declare a global type in a way that it would reside in an namespace? Plain simple typedef does not work.
For a forward declaration to work, you need to forward declare an object in the proper namespace. Since the original object resides in the global namespace, you need to forward declare it in the global namespace.
If you don't like that, you can always wrap the thing in your own structure:
namespace foo {
struct libDataWrapper; }
and in your own cpp define this structure. Or you can always resort to void* and the like, if you're up to that sort of thing.
since you are using pointer, i''' just forward declare a dummy object inside your own namespace, then use reinterpret_cast to bind the actual object to existing pointer.
your-source.h
namespace foo {
//forward declare
class externalObj;
class yourObj
{
public:
yourObj();
~yourObj();
void yourFunction();
private:
externalObj* pExt;
};
}
your-implementation.cpp
#include "your-source.h"
#include "externalObj-header.h"
namespace foo {
yourObj::yourObj() :
pExt ( reinterpret_cast<externalObj*>(new ::externalObj()) )
{
}
yourObj::~yourObj()
{
}
void yourObj::yourFunction()
{
reinterpret_cast<::externalObj*>(pExt)->externalFunction();
}
}
Can't you just simply wrap the include for the third-party library in its own namespace?
namespace ThirdParty {
#include "thirdparty.h"
}
namespace foo {
... your code
ThirdParty::LibData *d;
}
I have to use an API provided by a DLL with a header like this
namespace ALongNameToType {
class ALongNameToType {
static void Foo();
}
}
Is there a way to use ALongNameToType::ALongNameToType::Foo without having to type ALongNameToType::ALongNameToType each time? I tried using using namespace ALongNameToType but got ambiguous symbol errors in Visual Studio. Changing the namespace name or removing it gives me linker errors.
I don't know what's ambiguous, but you can avoid all conflicts with other Foo functions like this:
namespace ALongNameToType {
struct ALongNameToType {
static void Foo();
};
}
typedef ALongNameToType::ALongNameToType Shortname;
int main() {
Shortname::Foo();
}
namespace myns = ALongNameToType;
It seems that you can't alias a class scope like this:
// second ALongNameToType is a class
namespace myns = ALongNameToType::ALongNameToType;
Maybe you could alias the function it self:
namespace foo
{
class foo
{
public:
static void fun()
{
}
};
}
int main()
{
void (*myfunc)() = foo::foo::fun;
myfunc();
}
using ALongNameToType::ALongNameToType::Foo;
if you just want to use it as Foo().
There are three ways to use using. One is for an entire namespace, one is for particular things in a namespace, and one is for a derived class saying it doesn't want to hide something declared/defined in a base class. You can use the second of those:
using ALongNameToType::ALongNameToType
Unfortunately this isn't working for you (due to the ambiguity of the namespace and the class having the same name). Combining this type of using with a previous answer should get rid of the ambiguity:
namespace alntt = ALongNameToType;
using alntt::ALongNameToType;
But once you've renamed the namespace, you really don't need the using statement (as long as you're comfortable writing the (shortened) namespace every time you use the class:
namespace alntt = ALongNameToType;
alntt::ALongNameToType a;
...