Accessing an enum in a namespace - c++

In a header I have a setup like this
namespace NS {
typedef enum { GOOD, BAD, UGLY }enum_thing;
class Thing {
void thing(enum_thing elem);
}
}
and of course another cpp file that goes along with that header. Then I have a thread cpp file that contains main(). In this cpp file I use that enum to pass to the method thing().
using namespace NS;
int main() {
Thing t();
t.thing(BAD);
}
and of course I get other errors from G++ saying BAD was not declared. Any help on how I could overcome this error?

After correcting numerous little syntax errors in the sample code, it compiles just fine for me. Check that you've spelled the names correctly. Can you access the enum as NS::BAD? Perhaps you haven't included the correct header? Make sure you have
#include "FileWithEnum.h" at the top.
namespace NS {
typedef enum { GOOD, BAD, UGLY }enum_thing;
class Thing {
public:
void thing(enum_thing elem){}
};
}
using namespace NS;
int main() {
Thing t;
t.thing(BAD);
return 0;
}
Test it yourself:
http://codepad.org/Uw0XjOlF

Can you avoid using a typedef? Just do:
enum Foobar {good, bad, hello};

It should work. It does for me (the variant by Mystagogue should also work). I understand you had some other error messages ?
You probably just have to fix the header to be syntaxically correct, like putting a semi-colon at the end of class Thing, etc. When the header will be OK, the message about BAD not in namespace should also disappear.

Related

Opaque struct in C++ as class member

I have not been able to find an answer on this, but my case is:
// vulkan_glfw_backend.hpp
struct alignas(8) VulkanGlfwWindowContext;
class MY_API VulkanGlfwBackend
{
// [...]
private:
VulkanGlfwWindowContext* mpContext;
};
And the source file, where I want to have the implementation:
// vulkan_glfw_backend.cpp
#include "vulkan_glfw_backend.hpp"
struct VulkanGlfwWindowContext
{
int numWindows;
GLFWwindow* windows[MAX_WINDOWS];
};
Initially, my compiler complained because it couldn't determine the alignment requirements for the class, which I suppose makes sense. Then I added the alignas attribute. But now I get an error message, which I cannot understand the logical reason for:
vulkan_glfw_backend.cpp:113:51: error: invalid use of incomplete type ‘struct VulkanGlfwWindowContext’
113 | for (int i = 0; i < mpContext->numWindows; i++)
Since I declare it explicitly as a pointer inside a class, the storage requirements should be clear. Additionally, it's an implementation detail how the memory layout of the struct looks, which the compiler knows at compile-time, because it is defined at the top of the source file.
So, why is this going wrong, and can I fix it somehow? For several reasons I desire to have an opaque type. Thanks!
Answering my own question :)
So this is one of those days, where I'm not completely posting the entire code as is (my apologies!). So, the entire thing is inside a namespace:
// header
namespace mynamespace
{
// vulkan_glfw_backend.hpp
struct alignas(8) VulkanGlfwWindowContext;
}
//source
#include "vulkan_glfw_backend.hpp"
using namespace mynamespace;
struct VulkanGlfwWindowContext
{
int numWindows;
GLFWwindow* windows[MAX_WINDOWS];
};
The reason for this going wrong - again, I don't understand the logics behind it. Anyways, this is the fix:
//source
struct mynamespace::VulkanGlfwWindowContext
{
int numWindows;
GLFWwindow* windows;
};
Apparently, C++ doesn't understand the definition without fully-qualified namespace prepended to the name. I have seen the same issue with functions - it is not enough to open the namespace, it must be included in the definition.
This confuses me, as it is not required when implementing class member functions, where the name of the class is sufficient, e.g. someclass::somemember() {}.
But it works now!

What if there is a name clash even after using namespace?

We usually use namespaces to avoid name clashes in C++. But what if there are two different libraries which have a class, that has the same namespace name and class name? Is there a work around?
(PS: I am pretty sure, that its a rare scenario, I never faced it, just happened to cross my mind)
The idea is to use something related to the company/group itself.
This way the collision is avoided.
It is highly unlikely that a profesional library would choose something trivial like MyNamespace.
It would be like Company::Project::Module.
This is even clearer in java where you have org.apache etc
It might happen, but its not very likely to do you much damage. Not only do the namespace names have to be exactly the same, you have to actually use both libraries. Chances are, if they've named their namespaces in some reasonable way, their names will indicate their purpose -- even if there are two libraries that use GenericXMLParser as their namespace, and probably have some class names in common, do you really expect to be using them both on one project?
This does make certain namespace names a bad idea, such as boost or Ogre. Anyone using those (except the original users) should expect their library to be unusable in many cases. A less common name, like Pie, is probably going to be fine for by far most people in by far most cases. If both libraries using Pie become widely used, one might have to change; in that case, the namespace renaming trick can be used to keep backwards compatibility with old code.
You can rename one of the namespace with
namespace <new> = <old>;
But that will only get you so far. Here is an example :
namespace aaa {
int foo() { return 42; }
}
namespace zzz {
int foo() { return -42; }
}
namespace bbb = aaa;
int main() {
aaa::foo(); //Original namespace is still there
bbb::foo(); //but it is also available with a new name
zzz::foo(); //No clash, that's what namespaces are for
return 0;
}
But since the rename is really just an alias, the aaa namespace stays. This code will get you a duplicate symbol error (no matter how deep it is buried in .h files) :
namespace aaa {
int foo() { return 42; }
}
namespace aaa {
int foo() { return -42; }
}
You can get around it somehow by wrapping the clashing namespace in your own namespace declaration, like this :
#include <stdio.h>
namespace aaa {
int foo() { return 42; }
}
namespace zzz {
#include "clash.h"
}
namespace aaa2 = zzz::aaa;
int main() {
printf("%d\n", aaa::foo()); //Original works
printf("%d\n", aaa2::foo()); //Non-clashing through alias
printf("%d\n", zzz::aaa::foo()); //Non-clashing real name
return 0;
}
But that solution too will work only in trivial code, because all the included files in clash.h will end up in the zzz namespace.
+I think renaming std is forbidden though, if only by common sense.

Creating a C++ namespace in header and source (cpp)

Is there any difference between wrapping both header and cpp file contents in a namespace or wrapping just the header contents and then doing using namespace in the cpp file?
By difference I mean any sort performance penalty or slightly different semantics that can cause problems or anything I need to be aware of.
Example:
// header
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
// cpp
namespace X
{
void Foo::TheFunc()
{
return;
}
}
VS
// header
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
// cpp
using namespace X;
{
void Foo::TheFunc()
{
return;
}
}
If there is no difference what is the preferred form and why?
The difference in "namespace X" to "using namespace X" is in the first one any new declarations will be under the name space while in the second one it won't.
In your example there are no new declaration - so no difference hence no preferred way.
Namespace is just a way to mangle function signature so that they will not conflict. Some prefer the first way and other prefer the second version. Both versions do not have any effect on compile time performance. Note that namespaces are just a compile time entity.
The only problem that arises with using namespace is when we have same nested namespace names (i.e) X::X::Foo. Doing that creates more confusion with or without using keyword.
There's no performance penalties, since the resulting could would be the same, but putting your Foo into namespace implicitly introduces ambiguity in case you have Foos in different namespaces. You can get your code fubar, indeed. I'd recommend avoiding using using for this purpose.
And you have a stray { after using namespace ;-)
If you're attempting to use variables from one to the other, then I'd recommend externalizing them, then initializing them in the source file like so:
// [.hh]
namespace example
{
extern int a, b, c;
}
// [.cc]
// Include your header, then init the vars:
namespace example
{
int a, b, c;
}
// Then in the function below, you can init them as what you want:
void reference
{
example::a = 0;
}
If the second one compiles as well, there should be no differences. Namespaces are processed in compile-time and should not affect the runtime actions.
But for design issues, second is horrible. Even if it compiles (not sure), it makes no sense at all.
The Foo::TheFunc() is not in the correct namespacein the VS-case. Use 'void X::Foo::TheFunc() {}' to implement the function in the correct namespace (X).
In case if you do wrap only the .h content you have to write using namespace ... in cpp file otherwise you every time working on the valid namespace. Normally you wrap both .cpp and .h files otherwise you are in risk to use objects from another namespace which may generate a lot of problems.
I think right thing to do here is to use namespace for scoping.
namespace catagory
{
enum status
{
none,
active,
paused
}
};
void func()
{
catagory::status status;
status = category::active;
}
Or you can do the following:
// asdf.h
namespace X
{
class Foo
{
public:
void TheFunc();
};
}
Then
// asdf.cpp
#include "asdf.h"
void X::Foo::TheFunc()
{
return;
}

referencing something from global namespace?

This is really trivial but I'm getting an error I didn't expect.
I have some code which is inside of a namespace
the following is some pseudocode that represents the structure of my code:
namespace A {
void init() {
initialize_kitchen_sink();
}
#include "operations.h" // declares shake_and_bake()
void foo() {
shake_and_bake();
}
void cleanup() {
// do nothin' cuz i'm a slob
}
}
error:
undefined reference to `A::shake_and_bake`
Turns out moving the #include outside the namespace will fix it.
As it was, the include would be in effect declaring all of the functions in operations.h inside the A namespace. Then it would search in vain for the implementations.
I figure instead of deleting my entire post i may as well leave it for that minute possibility that someone else may stumble upon a similar problem and be enlightened.
To answer precisely to your question, you can reference something from the global namespace by using :: as your first statement as in :
void foo() {
::shake_and_bake();
}
Of course, your answer, for this special case is right though.

C++ Multiple classes with same name

Say I have two different cpp files. Both declare classes with the same name, but perhaps a totally different structure (or perhaps the same structure, different implementation). The classes do not appear in the header files. (As an example, suppose they are Node classes for different list classes.)
I've seen these classes conflict. Is this expected by the standard? What solutions are there to this problem?
UPDATE:
As suggested by answers/comments, anonymous namespaces are what I was looking for.
The standard way around this problem is to wrap the classes in different namespaces.
It violates One Definition Rule. It's hard for compiler to detect the error, because they are in different compilation units. And even linker cannot detect all errors.
See an example in http://www.cplusplus.com/forum/general/32010/ . My compiler and linker (g++ 4.2.1) can build the final executable without any error, but the output is wrong.
If I change the example a bit, I get segmentation fault.
// main.cpp
#include <iostream>
#include <list>
using namespace std;
struct Handler
{
Handler() : d(10, 1.234) {}
list<double> d;
};
extern void test_func();
int main(void)
{
Handler h;
cout << h.d.back() << endl;
test_func();
return 0;
}
// test.cpp
#include <iostream>
#include <string>
using namespace std;
struct Handler
{
Handler() : d("test Handler") {}
string d;
};
void test_func()
{
Handler h;
cout << h.d << endl;
}
It's recommended to differentiate you class by namespace. For example of Node, you can use nest class and define the Node in the parent list class. Or you can add you class in anonymous namespace. See How can a type that is used only in one compilation unit, violate the One Definition Rule?
I'm not sure if I'm missing some detail here, but you wrap each class in a namespace.
namespace A {
class Node { };
}
namespace B {
class Node { };
}
Then you can use A::Node or B::Node.
You can use namespace to have multiple classes with same name by sub-scoping them in different namespaces. See: http://www.cplusplus.com/doc/tutorial/namespaces/
I've seen these classes conflict. Is this expected by the standard?
The standard says you can't do that. It would violate the one definition rule. (How to fix this has already been covered in other answers)