I have an enum in the header:
namespace somespace
{
namespace internal
{
class SomeClass
{
public:
typedef enum
{
kNone = 0,
kKaka = 1,
}SomeEnum;
}
}
}
In the cpp, we sometimes use an anonymous namespace with the helper functions.
#include <somespace/internal/SomeClass.h>
using somespace::internal;
namespace
{
bool helpMe(SomeEnum& foo) //does not recognize the enum in the header
{
}
}
void SomeClass::memberMethod
{
}
But I cannot access the SomeEnum in the .cpp file. Why is that?
How can I get around this without polluting the internal namespace for example?
SomeEnum is scoped to the class name it is declared in. To use it you need SomeClass::SomeEnum. This assumes that SomeClass is accessible in the scope you have it. If not then you need somespace::internal::SomeClass::SomeEnum
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;
...
}
We're attempting to hide a class behind a new namespace, however we'd like to keep the original name.
namespace first {
class Logger { ... };
}
namespace second {
using Logger = first::Logger;
}
error: definition of type 'Logger' conflicts with type alias of the
same name
class Logger;
Yes we can:
namespace first {
class Logger { };
}
namespace second {
typedef first::Logger Logger;
}
typedef is apparently equivalent to using (in C++11), just more wieldy.
Right-o, this was due to a forward declaration of type class Logger within our own codebase.
namespace first {
class Logger { ... };
}
namespace second {
using Logger = first::Logger;
... some time later ...
class Logger;
}
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;
...
I have some inline functions contained within a namespace in a header file and am not currently in a position to move them into a cpp file. Some of these inline functions use magic constants, for example:
// Foo.h
namespace Foo
{
const int BAR = 1234;
inline void someFunc()
{
// Do something with BAR
}
}
However, I want to make these magic constants private - any ideas how? My first thought was to use an anonymous namespace thus:
// Foo.h
namespace Foo
{
namespace
{
// 'private' constants here
const int BAR = 1234;
}
inline void someFunc()
{
// Do something with BAR
}
}
However, this doesn't work and Foo::BAR is available to any cpp file that includes Foo.h? Is there a way to do this without creating an implementation cpp file?
You can't, anonymous namespaces work for the translation unit they are defined in (or included into in your case).
You could consider moving them into a detail namespace to signal to the user that they are internal details:
namespace foo {
namespace detail {
int magic = 42;
}
// ... use detail::magic
}
How about:
namespace Foo {
class foo_detail {
private:
enum {
BAR = 1234,
};
friend void someFunc();
};
inline
void someFunc() {
// something with foo_detail::BAR
}
}
This makes the constant nonaccessible for anyone else than the functions you mark as friends. You can make the class nonconstructable by making the constructor private to make sure that noone does try to instanciate the class.
Put them in a special namespace or name them specially, combined with a project convention that such things are non-public:
namespace foo {
namespace detail { // as in "implementation details"
inline int answer() { return 42; }
const int perfect = 28;
}
std::string _question(); // not part of foo's "public interface" by convention
int this_is_public() {
using namespace detail; // now don't have to prefix detail::
return answer() + perfect + _question().length();
}
}
Anyone using names documented as non-public will circumvent any "protection" you try; which highlights the real concern: documenting what's part of the public interface and may be relied upon.
Unnamed namespaces solve a different problem: getting names unique to a particular TU. They won't help here.