Using a class in a namespace with the same name? - c++

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;
...

Related

C++ friend class of the same name in different levels of a nested namespace

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;
}
}
}

Hiding declaration in cpp file

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;
...
}

Using a namespace only inside one specific class file

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.

Why is it not possible to define a fully-qualified function within a foreign namespace? May I know what the standard says?

Is this is wrong? Why? May I know what the standard says?
namespace N{
namespace N1{
namespace N2{
struct A{
struct B{
void fun();
};//B
}; //A
} //n2
}//n1
namespace N3{
void N1::N2::A::B::fun(){} //error
}//n3
}//n
int main()
{
return 0;
}
May I know why it is failing?
This is invalid due to ยง9.3/2:
A member function definition that appears outside of the class definition shall appear in a namespace scope enclosing the class definition.
The scope of the namespace N3 does not enclose the definition of the class B
Here is a much simpler example, that also fails to compile:
namespace N1 {
void f() ;
}
namespace N2 {
void N1::f() { }
}
To put the answer in plain English, the definition of a function or method which belongs to a class (or struct) needs to be in the same namespace as the class definition. In other words, you can't declare the function in one namespace and then define it in another.

Forward declare a global type inside a namespace

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;
}