error: statement cannot resolve address of overloaded function C++ - c++

I am studying C++ by book and was trying to test simple coding for a looped game combat. A switch inside a while loop.
damage = greatsword[0] + player[1] - enemy[2]; endl;
error: statement cannot resolve address of overloaded function|
I have this error in 4 different code lines and in each one it has 'damage' so I assume its some problem with that. I have damage declared as an int and set to 0 before trying to change it to the attack value. I can provide more of the code if needed. I also tried changing the name from x to dmg to see if that was the problem

You have a trailing endl; which you probably did not mean to include. std::endl is a function which is used when printing to an output stream; usually you'll see cout << ... << endl;, but otherwise it should not be used.

std::endl, as used as a stream manipulator, is actually a function.
You probably achieve a similar or related error message by doing this
void f(); // don't need to define f()
int main()
{
f; // should be f() to call the function
}
So remove the statement endl;

Related

Why is my function "missing argument lists"?

I'm not sure what I've done wrong in my project. I have two files, an airports.h header file and a main source file. In the main source file I have
string code,name;
int deptax, conntime;
cin >> code >> name >> deptax >> conntime;
Airport myAirport(code,name,deptax,conntime);
cout << myAirport.getCode << endl;
and in the airports.h header file I have
class Airport{
public:
Airport(string code, string name, int departureTax, int connectionTime)
:code(code),
name(name),
departureTax(departureTax),
connectionTime(connectionTime)
{...}
string getCode(){
return code;
}//then getName, getDepTax, getConnTime...
}
When I run the main source file, I get the error "error C3867: 'Airport::getCode': function call missing argument list; use '&Airport::getCode' to create a pointer to member" which is in line 5 up there.
I'm a beginner so I'm not sure why it's telling me to do this. Shouldn't .getCode() work how it's written? When I looked for previous solutions to this online, the solution was always something that was unrelated to the "pointer to member" error, so I think I may simply be using c++ in a way that it's not meant to be used.
cout << myAirport.getCode() << endl;
Note the parenthesis needed to call the function. The reason for requiring the () to be there is that a function named without them actually has a valid meaning and it is quite different to calling the function.
You need to call your function
myAirport.getCode()
instead of
myAirport.getCode
You're missing the () in the
cout << myAirport.getCode << endl;
after getCode ,should be getCode()

Linkage between files - how exactly does it work?

So I've been reading about this but couldn't find anything that'd explain the behavior of this code below to me:
header.hpp:
class TESTING{
private:
int num;
public:
TESTING(int);
};
void testing(int, int);
def.cpp:
#include "header.hpp"
#include <iostream>
using namespace std;
TESTING::TESTING(int num = 100){
this->num = num;
cout << "init with: " << this->num << endl;
}
void testing(int a = 500, int b = 200){
cout << "a: " << a << ", b: " << b << endl;
}
int main(){
TESTING test1;
TESTING test2(5);
testing();
testing(1);
testing(1, 2);
}
So far so good and working as intended, the output then is:
init with: 100
init with: 5
a: 500, b: 200
a: 1, b: 200
a: 1, b: 2
But then when I cut the "int main" function and paste it into the following Main.cpp below
Main.cpp:
#include "header.hpp"
int main(){
//TESTING test1;//error: assumed to be default constructor
TESTING test2(5);
//testing();//error: too few arguments
//testing(1);//error: too few arguments
testing(1, 2);
}
I'd get the errors mentioned in the comments above but still the output:
init with: 5
a: 1, b: 2
Which then means that it does link itself to def.cpp but with some sort of minimum visibility(?).
Why's this happening?
The purpose of this Main.cpp file is to have the main function that'll run all the other c++ files in that project, is there a general better way to achieve that than the way I tried? If so, does that way apply to the code mentioned here? Or is my code just written badly?
P.S: I'm new to c++, please be gentle :d
Default arguments don't magically transfer across source files. Think about it - how is the compiler processing main.cpp supposed to know that, in a different source file, you gave default arguments to some parameters?
Formally, default arguments are specific to any given scope:
8.3.6/4 For non-template functions, default arguments can be added in later declarations of a function in the same scope. Declarations in
different scopes have completely distinct sets of default arguments...
Even in the same source file, you can declare the same function to have different default arguments in different scopes. The compiler would happily substitute whatever default arguments, if any, are specified by the declaration visible in the current scope.
On an unrelated note, the word "linkage" is a term of art - it has a very specific meaning in C++. This notion of linkage is largely irrelevant to your question, at least insofar as it relates to default arguments (I just point it out for the benefit of readers who might be confused by the question's title). The set of default arguments is not part of the function name or signature, and doesn't affect its linkage, its ability to be used across scopes and translation units.

Function 'not declared in this scope', but it is! Isn't it?

'initPhysics' was not declared in this scope.
I have simplified my program as much as I could; here it is:
helloworld.hpp
#ifndef HELLOWORLD_HPP
#define HELLOWORLD_HPP
class testWorld {
public:
testWorld() {}
~testWorld() {}
void initPhysics();
};
#endif
hello.cpp
#include "helloworld.hpp"
#include <iostream>
using namespace std;
void testWorld::initPhysics() {
cout << "Initiating physics..." << endl;
}
int main(int argc,char** argv) {
cout << "Hello World!" << endl;
testWorld* world;
world = new testWorld();
world<-initPhysics();
return 0;
}
I compile with the command
g++ -c hello.cpp
and get the error
hello.cpp: In function ‘int main(int, char**)’:
hello.cpp:14:21: error: ‘initPhysics’ was not declared in this scope
Why doesn't the compiler see the declaration of initPhysics, even though I included helloworld.hpp?
It should be world->initPhysics(), not world<-initPhysics()
Your version is being read as the expression "world is less than -1 multiplied by the result of the global function initPhysics()" and it's that global function that it can't find.
And although this is obviously test code, I'd just like to point out that if you allocate an object with new, you must explicitly delete it somewhere.
world<-initPhysics() should be world->initPhysics()?
Learn to read the -> operator (not <-!) in ptr->member as "member in whatever ptr points to", in other words: it is a somewhat literal representation of an actual pointer. So in your case it should be
world->initPhysics(); // note the ->, not <-
However, while this answers your question, it's far from sufficient. There's several other problems with your code.
There's no need to first create an uninitialized pointer, and then initialize it. That's error-prone, and you should instead initialize it immediately:
testWorld* world = new testWorld();
world->initPhysics();
Note that in C++ every object created using the new operator needs to be destroyed explicitly using the delete operator:
delete world; // sounds scary, BTW
You seem to be coming from a language like Java or C#, where everything must be new'd. In C++ this is not true. By default you should create objects on the stack, rather than on the heap:
testWorld world;
world.initPhysics();
But there's still a problem with your code. What you have now is what's known as two-phase construction. As a user of your class I need to remember to call an initialization function before I use an instance of it. But that's what constructors are for! A constructor should fully initialize an object, so that it is in a usable state. You should call your initialization function from the constructor instead:
testWorld() {initPhysics();}
Physics is an integral part of the world, and shouldn't be added as an afterthought. :)
You want world->initPhysics(); instead of world<-initPhysics();
world<-initPhysics();
Here, your arrow is in the wrong direction. You should have :
world->initPhysics();
world<-initPhysics(); should be world->initPhysics();

C++ function prototypes?

Here goes newbie question number 5, but I don't have a teacher.. so.. anyhow here we go:
I'm wondering if is necessary to have function prototypes at the top of the file, instead of putting the main function to the end of the file and create all the function at the top of the file. As far as I can tell, VC++ and G++ both are not complaining. Is there standards that disallows me to do so?
It seems rather annoying to have to change the prototype when you change a function parameters and return types.
Example:
#include <iostream>
void say_hi(){
std::cout << "hi" << std::endl;
}
int main(){
say_hi();
return 0;
}
This declares but does not define the function say_hi:
void say_hi();
This both declares and defines the function say_hi:
void say_hi(){
std::cout << "hi" << std::endl;
}
You can declare a function many times; you can only define it once.
A function must be declared in the file before you can call it. A function must be defined somewhere--in the same file before or after you call it or maybe even in a different file.
So, yes, this is perfectly fine.
You are correct; if you define all your functions above where they are called, you don't need function prototypes. The actual function definition serves the same purpose as a separate declaration.
This works when you have tiny functions. It works less well when they get long. Or when you have more than one file of code. As a matter of style, many teachers demand that even tiny applications be written with the structure that serves large applications well.

question with longjmp

I want to use longjmp to simulate goto instruction.I have an array DS containing elements of struct types (int , float, bool ,char). I want to jump to the place labled "lablex" where x is DS[TOP].int_val. how can I handle this?
sample code :
...
jmp_buf *bfj;
...
stringstream s;s<<"label"<<DS[TOP].int_val;
bfj = (jmp_buf *) s.str();
longjmp(*bfj,1);
but as I thought it's having problem what should I do?
error:
output.cpp: In function ‘int main()’:
output.cpp:101: error: invalid cast from type ‘std::basic_string, std::allocator >’ to type ‘__jmp_buf_tag (*)[1]’
You probably don't want to use longjmp at all but I hate it when people answer a question with "Why would you want to do that?" As has been pointed out your longjmp() usage is wrong. Here is a simple example of how to use it correctly:
#include <setjmp.h>
#include <iostream>
using namespace std;
jmp_buf jumpBuffer; // Declared globally but could also be in a class.
void a(int count) {
// . . .
cout << "In a(" << count << ") before jump" << endl;
// Calling longjmp() here is OK because it is above setjmp() on the call
// stack.
longjmp(jumpBuffer, count); // setjump() will return count
// . . .
}
void b() {
int count = 0;
cout << "Setting jump point" << endl;
if (setjmp(jumpBuffer) == 9) return;
cout << "After jump point" << endl;
a(count++); // This will loop 10 times.
}
int main(int argc, char *argv[]) {
b();
// Note: You cannot call longjmp() here because it is below the setjmp() call
// on the call stack.
return 0;
}
The problems with your usage of longjmp() are as follows:
You don't call setjmp()
You haven't allocated the jmp_buf either on the stack or dynamically. jmp_buf *bfj is just a pointer.
You cannot cast a char * to jmp_buf * and expect it to work. C++ not a dynamic language it is statically compiled.
But really, it is very unlikely that you should be using longjmp() at all.
The normal way to use longjump is incombination with setjump() as described here. You seem to want to make a jumptable as normally done with switch-case or with virtual functions.
Anyway, labels in code (compile-time) are not reachable with strings (run-time), so that is already your first problem. You would really need to find out the address of where you want to jump to and my best guess would be to put setjump()'s where your labels are.
You've totally failed C++. Firstly, goto's are bad, and not for the uninitiated- there's a reason that for, while, break, continue etc exist. Secondly, you're trying to convert a string into an identifier, which is impossible at runtime unless you code it yourself. Thirdly, you're.. trying to cast a const char* to a jmp_buf*? What?
In addition to that, C++ does have goto. But if you want to jump given an int, then you're going to have to switch it, e.g.
switch (DS[TOP].int_val) {
case 1:
goto label1;
break;
case 2:
goto label2;
break;
default:
throw std::runtime_error("Unrecognized label!");
}
Sounds like you want a function pointer:
((void(*)(void))*((int *)DS[TOP].int_val))();
This treats DS[TOP].int_value like an address and jumps to it. If you wanted to jump to where DS[TOP].int_value is located, you would:
((void(*)(void))*((int *)&DS[TOP].int_val))();
Either way, ugly, ugly code. But it should do what you want.
When setjmp() is called, the system effectively takes a snapshot of the call and parameter stack. This snapshot will remain valid until user code exits the block in which setjmp() was called; if longjmp() is called with that snapshot, execution will resume as though the setjmp() were returning for the first time, except that instead of returning zero, it will return the second parameter passed to longjmp(). It is very important to note that calling longjmp() with an invalid snapshot may have very bad effects. In some systems, such an invalid call may "seem" to work, but corrupt the system in such a way that it later crashes.
Although setjmp()/longjmp() are sometimes appropriate in pure C programs, having a C program call setjmp() to create a snapshot, and then call some C++ code which in turn calls longjmp() to return to that snapshot, is a recipe for disaster. Nearly all situations where one would want to do that may be better handled using exceptions.