referencing something from global namespace? - c++

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.

Related

Why separating template definition/declaration sometimes work

I'm wide awake at 1AM trying to figure out a compilation error I'm having.
I can't really write the exact code but I'll do my best to make my question clear.
ClassWithTemplateFunction.hpp
#include "StructA.hpp"
#include "ClassB.hpp"
class ClassWithTemplateFunction
{
template<typename A>
void MyTemplateFunc();
}
ClassWithTemplateFunction.cpp
template<typename T>
void ClassWithTemplateFunction::MyTemplateFunc()
{
// code block
}
StructA.hpp
struct ClassWithTemplateFunction;
struct StructA
{
void StructAFunc(ClassWithTemplateFunction* templ);
}
StructA.cpp
#include "ClassWithTemplateFunction.hpp"
#include "StructA.hpp"
StructA::StructAFunc(ClassWithTemplateFunction* templ)
{
templ->MyTemplateFunc<SomeTemplate>();
}
The above codes work great. "SomeTemplate" is also another class. But then I added a new class which also uses the template function:
ClassB.hpp
class ClassWithTemplateFunction;
class ClassB
{
void ClassBFunc();
}
ClassB.cpp
#include "ClassB.hpp"
#include "ClassWithTemplateFunction.hpp"
void ClassB::ClassBFunc(ClassWithTemplateFunction* templ)
{
templ->MyTemplateFunc<SomeTemplate>();
}
And for some reason, this now introduced a linker error (undefined reference to MyTemplateFunc()). I can't figure out why it suddenly produced this issue. Obviously it can be fixed by moving the definition to the header file, but I want to understand, before adding ClassB, the code works just fine.
If ClassWithTemplateFunction.cpp instantiates MyTemplateFunc with some template arguments somehow (e.g. by calling it), you'll be able to use MyTemplateFunc with the exact same arguments anywhere in the program.
That's why you don't get an undefined reference in the first case.
But it's not possible for an invocation of MyTemplateFunc with the exact same template arguments in a different file to cause an undefined reference. Please check if the template argument is really the same in both cases.

While seperating classes, using a function in cpp file causes errors

So i just learned how to seperate classes and the youtube totourial is stressing on doing this alot, here's the link
https://www.youtube.com/watch?v=NTip15BHVZc&list=PLAE85DE8440AA6B83&index=15
My code is the exact same as his, and in the cpp file theres this thing:
mainClass::myfunction; (mainclass is the name of my class, myfunction is my function)
when i try to execute my program, it gives an error:
unidentified reference to 'mainClass::myfunction()'
here's my main.cpp file code:
#include <iostream>
#include "mainclass.h"
using namespace std;
int main()
{
mainClass bo;
bo.myfunction();
return 0;
}
here's my mainclass.h code:
#ifndef MAINCLASS_H
#define MAINCLASS_H
class mainClass
{
public:
myfunction();
};
#endif // MAINCLASS_H
my mainclass.cpp:
#include "mainclass.h"
#include <iostream>
using namespace std;
mainClass::myfunction()
{
cout << "I am a banana" << endl;
}
I don't know much about these so could you just tell me what the errors here are, because i copied everything correctly from the guy's totourial but still it doesn't work
P.S: this happens to me alot, i understand everything, nothing works, i copy everything, nothing works, and then i literally do exactly what the person is doing, still nothing works on all three of PC's, so i dont think the problem is with the devices lol
I doubt you completely copied and pasted that code because I'm fairly sure a teacher shouldn't be teaching having functions without a specified return type, but let's jump into it anyways...
Possibility #1
You meant to create a constructor for the class. In that case, please make sure the constructor function has the same name as the class. Also, you can't call it through .mainClass(), as it is a constructor.
class mainClass
{
public:
mainClass();
};
mainClass::mainClass()
{
cout << "I am a banana" << endl;
}
Possibility #2 You meant to create the class member function myfunction. You really should be specifying what return type your function is of. Some compilers will auto-assume int return type, and so the function you created is int myfunction();, but you really should be specifying it as void myfunction(); since you didn't return anything. Addl. info: Does C++ allow default return types for functions?
Next, change how you are giving the definition, by adding the return type.
void mainClass::myfunction()
{
cout << "I am a banana" << endl;
}
Possibility #3 Those should work, but another issue is that you might not have linked mainclass.cpp, so there is no definition available. In code blocks, right click on the project name and hit Add Files, then add the mainclass.cpp so the linker can define mainClass::myfunction().
To troubleshoot if the mainclass.cpp is being built with the project, try adding
#error I'm included! to the file mainclass.cpp after #include "mainclass.h". If you get an error I'm included!, then it is linked and you can remove the #error.

Why is the declaration/definition order still important in C++?

For many times now, I have had problems with the declaration and definition order in C++:
struct A {
void Test() { B(); }
};
void B() {
A a;
}
Of course this can be solved by predeclaring B(). Usually this is good enough to solve any of these problems. But when working with module based header-only libraries or similarily complex include systems, this declaration/definition concept can be really painful. I have included a simple example below.
Nowadays most modern language compilers do a two-pass over the source files to build the declarations in the first pass and process the definitions in the second one. Introducing this scheme into C++ shouldn't break any old code either. Therefore,
Why hasn't this, or a similar approach, been introduced into c++ already?
Are there any relevant clauses in the current standard inhibiting this approach?
Example
This is an example of a module based header library, which has blocking includes because of missing predeclarations. To solve this, the user of the library would have to predeclare the "missing" classes, which is not feasible.
Of course this problem might be solved by using a common include header that orders all declarations before definitions, but with a two-pass this code would also work, no modification required.
oom.h
#pragma once
#include "string.h"
struct OOM {
String message;
};
string.h
#pragma once
#include "array.h"
struct String {
Array data;
};
array.h
#pragma once
struct Array {
void Alloc();
};
#include "oom.h"
void Array::Alloc() { throw OOM(); }
str_usage.cpp
#include "string.h"
int main() {
String str;
}
void f(int);
void g() { f(3.14); }
void f(double);
g currently calls f(int), because it's the only f visible. What does it call in your world?
If it calls f(double), you just broke copious existing code.
If you came up with some rules to make it still call f(int), then that means if I write
void g2() { f2(3.14); }
void f2(double);
and then introduce a worse match for the argument - say, void f2(int); before g2, g2 will suddenly start calling the wrong thing. That's a maintainability nightmare.
A much simpler solution is to separate class definitions from function definitions:
struct A {
void Test();
};
struct B {
A a;
};
inline void A::Test() {
B();
}
There are ambiguities in the C++ grammar that can only be resolved if you know what an identifier refers to.
For example:
a * b;
can be either a multiplication if a is a variable, or a pointer declaration if a is a type. Each of these leads to a different parse tree, so the parser must know what a is.
This means that parsing and name resolution cannot be performed in separate passes, but must be done in one pass, leading to the requirement to pre-declare names.

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

Accessing an enum in a namespace

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.