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.
Related
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;
...
}
Is it possible to add something to a namespace alias?
Or how can I achieve the following:
using KdTree = ExternalLibrary::Special::KdTree;
namespace KdTree{
class MySpezial {};
};
That does not work, but the following works:
using KdTree = ExternalLibrary::Special::KdTree;
namespace ExternalLibrary{ namespace Special { namespace KdTree{
class MySpezial {};
}}};
Is the first method just prohibited by the standart?
The first example is currently not allowed and probably won't be in C++1Z either, but note that a recent proposal is allowing
namespace ExternalLibrary::Special::KdTree {
class MySpezial {};
}
This is already implemented in Clang.
I have a couple functions that I want to use in many different classes. I have a couple classes that are derived from one base class and so tried to make it so that the base class held the functions and then the child classes could just call them. This seemed to cause linking errors, and so following advice from this question (Advantages of classes with only static methods in C++) I decided to give namespaces a swing, but the only file that is included by every header/file is resource.h, and I don't want to put a namespace for my functions in there as it seems to specialised to mess with.
My question is, how do I make a class that only includes a namespace, or the functions I want to use, so that I can just include this class and use the functions as desired?
Thank you in advance for the help, the answers I've found on the internet only focus on one file, not multiple files like I'm hoping to address :)
You seem confused about how namespaces are used. Here are some things to keep in mind when working with namespaces:
You create a namespace using the syntax namespace identifier { /* stuff */ }. Everything between the { } will be in this namespace.
You cannot create a namespace inside a user-defined type or function.
A namespace is an open group construct. This means you can add more stuff into this namespace later on in some other piece of code.
Namespaces aren't declared unlike some of the other language constructs.
If you want certain classes and/or functions inside a namespace scope, enclose it with the namespace syntax in the header of where it's defined. Modules using those classes will see the namespace when the headers get #include'd.
For example, in your Entity.h you might do:
// Entity.h
#pragma once
namespace EntityModule{
class Entity
{
public:
Entity();
~Entity();
// more Entity stuff
};
struct EntityFactory
{
static Entity* Create(int entity_id);
};
}
inside your main.cpp you access it like this:
#include "Entity.h"
int main()
{
EntityModule::Entity *e = EntityModule::EntityFactory::Create(42);
}
If you also want Player to be inside this namespace then just surround that with namespace EntityModule too:
// Player.h
#pragma once
#include "Entity.h"
namespace EntityModule{
class Player : public Entity
{
// stuff stuff stuff
};
}
This works because of point #3 above.
If for some reason you feel you need to create a namespace inside a class, you can simulate this to an extent using nested classes:
class Entity
{
public:
struct InnerEntity
{
static void inner_stuff();
static int more_inner_stuff;
private:
InnerEntity();
InnerEntity(const InnerEntity &);
};
// stuff stuff stuff
};
Some important differences and caveats doing it this way though:
Everything is qualified with static to indicate there's no specific instance associated.
Can be passed as a template parameter.
Requires a ; at the end.
You can't create a convenient shorthand with abusing namespace Entity::InnerEntity;. But perhaps this is a good thing.
Unlike namespaces, class and struct are closed constructs. That means you cannot extend what members it contains once defined. Doing so will cause a multiple definition error.
You can put anything in a namespace, but you can't put namespaces inside things ( that's not a very formal way of saying it but I hope you get what I mean.
Valid
namespace foospace
{
class foo
{
public :
foo();
~foo();
void eatFoo();
};
}
Invalid
namespace foospace
{
class foo
{
public :
foo();
~foo();
namespace eatspace
{
void eatFoo();
}
};
}
I'm not 100% certain that the second example wouldn't compile, but regardless, you shouldn't do it.
Now, from your comments it sounds like you want something like this :
In the file Entity.h, your entity class definition :
namespace EntitySpace
{
class Entity
{
public :
Entity();
~Entity();
};
}
In the file Player.h
#include "Entity.h"
namespace EntitySpace
{
class Player : public Entity
{
public :
Player();
~Player();
};
}
In the file main.cpp
#include "Player.h"
int main()
{
EntitySpace::Player p1;
EntitySpace::Player p2;
}
So you call upon Player in the EntitySpace namespace. Hope this answers what you were asking.
If you use namespaces for separation of modules / structurization the nesting and indentation within the the header file increases dramatically. Is there a way to write the following code in a shorter way?
namespace A
{
namespace B
{
namespace C
{
namespace D
{
namespace E
{
template <typename T>
public class X
{
public: ...
e.g. like
namespace A::B::C::D::E
{
template<typename T> ...
}
in the header file in c++?
No, that nested namespace syntax has been suggested before at different times and places but isn't valid.
You don't need to indent though
namespace A { namespace B { namespace C {
// ...
} } } // namespace A::B::C
You can use namespace aliasing. This doesn't work for extending existing namespaces, but rather for easier access.
You can use macros to extend existing namespaces, but it you need to do this, you've probably got a deeper namespace hierarchy than you need or want.
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;
...