I have a header in which I declare a function. Then I create the function and try to use it but i get an error. It is by reference but I don't know why it is not working.
struct.h
#ifndef LISTSTRUC_H_
#define LISTSTRUC_H_
template <class T> struct Array{
int days;
T * M;
Array( int size ) : days(size), M(new T[size])
{
}
~Array()
{
delete[] M;
}
};
void currentDay();
template <class Expe>
void dummyData(Array<Expe> &);
#endif /* LISTSTRUC_H_ */
struct.cpp
void dummyData(Array <Expe> &A){
for(int i=0; i<31; i++){
A.M[i].Expe::setObj((i*3),(i*1),(i*6),(i*2),(i*4),(i*5));
}
}
M.cpp(Main cpp)
int main(){
//Main function of the program. no pre/ post condition.
Array <Expe> A(31); // Work space
Array <Expe> B(31); // Backup space
dummyData(&A); // error
}
ERROR:
..\M.cpp:22:14: error: no matching function for call to 'dummyData(Array<Expe>*)'
dummyData(&A);
should be:
dummyData(A);
Rationale:
Your function takes a reference not a pointer, &A means you are passing address of the type which can only be received in by a pointer to that type and you don't have that overloaded version of the function, hence the error.
If passing object by reference, don't pass its address, like you did here:
dummyData(&A);
Just pass the object itself (as reference is its alias):
dummyData(A);
You shouldn't put reference & to pass a variable by reference, simply pass it.
dummyData(A);
Passing by reference means that you are not copying the object, instead you are using the object itself and, if passed as variable (not const) changes will affect it.
dummyData(&A);
should be
dummyData(A);
The & operator in this context is taking the address of A which is a pointer. To pass a reference you just use the actual variable name.
Related
I though that I understood iterators and addressing etc. but obviously not. See my below code below which is purely an example.
I need to be able to pass by pointer or reference each structure of mystructs to MyFunc(). The function should be able to update the actual structure that is passed, and not by copy or value.
I receive the compiler error :
error: cannot convert 'MY_STRUCT' to 'MY_STRUCT*' for argument '1' to 'void MyFunc(MY_STRUCT*)'
If I just pass the iterator address, this also doesn't work.
What is the correct way to do this. Thanks in advance.
typedef struct
{
int var1;
int var2;
std::string name;
}MY_STRUCT;
std::list<MY_STRUCT> mystructs;
void MyFunc(MY_STRUCT*)
{
// Do something
}
// populate the list with structs etc.. not included here
//.....
for (std::list<MY_STRUCT>::iterator it = mystructs.begin();it != mystructs.end(); ++it)
{
MyFunc(*it);
}
Passing by reference in C++ is done with:
void MyFunc(MY_STRUCT&)
{
// Do something
}
So your call would be correct, what you currently want is to pass the pointer, which you can do with dereferencing the dereferenced iterator (by passing the address of the dereferenced object):
void MyFunc(MY_STRUCT*)
{
// Do something
}
// populate the list with structs etc.. not included here
//.....
int main() {
for (std::list<MY_STRUCT>::iterator it = mystructs.begin();it != mystructs.begin(); ++it)
{
MyFunc(&*it);
}
}
Your function requires a pointer, use & to get the address of something.
MyFunc(&*it);
*it returns a reference to the MY_STRUCT object, you need to use & to convert that reference to a pointer. This is normal, the fact that you are using iterators makes no difference at all.
The alternative (maybe better in C++) would be to convert your MyFunc function to take a reference instead of a pointer.
I'm trying to call a method to add to an object to a vector within another object. I'm getting the error;
'': Illegal use of this type as an expression
Within my program I declare an object to store my node in the main;
accountStream *accountStore = new accountStream;
Then call the function;
new_account(&accountStore);
The new_account function is as;
void new_account(accountStream &accountStorage)
{
newAccount *account = new newAccount;
(&accountStorage)->pushToStore(account);
}
The account stream class has a vector that receives it, but there is where my error is;
class accountStream
{
public:
accountStream();
~accountStream();
template <class account>
void pushToStore(account);
private:
std::vector <newAccount*> accountStore;
};
template<class account>
inline void accountStream::pushToStore(account)
{
accountStore.push_back(account);
}
The error is on the second last line;
accountStore.push_back(account);
I've got a feeling it's something to do with the way I'm passing the object into the method, but after messing around for a while I haven't been able to pinpoint where exactly I've gone wrong.
2 problems:
new_account(&accountStore); is wrong, use new_account(*accountStore); to match the argument type.
accountStore.push_back(account); is wrong. account is type not object. Add some argument to the function.
Several issues:
You must specify the variable name here (and not only the type):
template<class account>
inline void accountStream::pushToStore(account c)
{
accountStore.push_back(c);
}
You must receive a pointer (not a reference to a pointer) here
void new_account(accountStream *accountStorage)
{
newAccount *account = new newAccount;
accountStorage->pushToStore(account);
}
You must call the function with a pointer as a parameter:
new_account(accountStore);
Alternatively, you can declare the variable (not a pointer to):
accountStream accountStore;
call the function:
new_account(accountStore);
and receive a reference:
void new_account(accountStream &accountStorage)
{
newAccount *account = new newAccount;
accountStorage.pushToStore(account);
}
As answered here already, you need to use *accountStore and not &accountStore because the function takes a reference and not a pointer to a pointer (which is what you get from using & operator on a pointer).
the second problem is here:
template<class account>
inline void accountStream::pushToStore(account)
{
accountStore.push_back(account);
}
you are declaring the function templated on the 'account' therefore account is a type, and what you are trying to do in the next line is push_back a type and not an object.
the correct code would be:
template<class account>
inline void accountStream::pushToStore(account acct)
{
accountStore.push_back(acct);
}
because account is the type while acct is an instance of the type account.
Have a structure:
scheduled_call {
MyClass* object;
int value;
void (MyClass::*setter)(const int)
}
For class:
MyClass {
void doSomething(const int);
}
The structure compiles all well, but when I try to call the value as function, it throws error:
I need to execute call saved in this structure. I tried this:
void executeIt(scheduled_call cl) {
cl.object->*(cl.method)(cl.value);
}
But I get:
error C2064: term does not evaluate to a function taking 1 arguments
My coding is based on C/C++ function pointer guide. I'm doing this as an experiment, if it fails I can fallback to switch statement of course.
Can anybody compile this under Visual Studio 2010?
You need to provide a valid member function pointer definition in your struct:
scheduled_call {
MyClass* object;
int value;
void (MyClass::*method)(int); // <<<<
}
void MyClass::*method;
Is not a valid function pointer to a class memeber function. To get that we need
void (MyClass::*method)(int)
An now method is a pointer to function like MyClass::doSomething()
The problem was in method call. This is wrong:
cl.object->*(cl.method)(cl.value);
This is correct:
(cl.object->*cl.method)(cl.value);
I'm having a small problem which I can't wrap my head around.
I have a function that looks like this:
template <typename T>
std::unique_ptr<Environment>& CreateEnvironment(sf::Vector2f& _position, bool _addToStatic = false);
This is my function pointer typedef
typedef std::unique_ptr<Environment>& (WorldEditor::*CreateEnvironmentPtr)(sf::Vector2f&, bool);
std::map<std::string,CreateEnvironmentPtr> listEnv;
And I'm trying to simply do this:
listEnv["test"] = &CreateEnvironment<Coin>(sf::Vector2f(200,200), false);
And i get the following error:
error C2440: '=' : cannot convert from 'std::unique_ptr<_Ty> *' to
'std::unique_ptr<_Ty> &(__thiscall WorldEditor::* )(sf::Vector2f
&,bool)'
I understand what the error is saying, but I don't know how to solve it. Also why does it even care about the return type when I'm pointing to the address of the function?
Best regards
nilo
problems such as these are often much better solved with std::function
std::map<std::string, std::function<void()> listEnv;
listEnv.emplace("test", [] {
CreateEnvironment<Coin>(sf::Vector2f(200,200), false);
});
to call:
listEnv.at("test")->second();
Based on your post I am not sure if you are attempting to create the member function pointer and map inside the CreateEnvironment class or outside of it, so I'll solve what I think is the more difficult problem of pointer to a separate object's member function.
I simplified your classes like so:
Environment
struct Environment
{
int i = 1;
};
Coin
struct Coin
{
int k = 0;
};
WorldEditor
struct WorldEditor
{
template <typename T>
std::unique_ptr<Environment> CreateEnvironment(int& _j, bool _addToStatic = false)
{
return std::make_unique<Environment>();
}
};
Solution: Map an object's member fn pointer, and then call it later
(I will be using C++11/14 syntax in my answer)
//declare a pointer to member function in WorldEditor
using CreateEnvironmentPtr = std::unique_ptr<Environment> (WorldEditor::*)(int&, bool);
//declare an object of type WorldEditor, because member function pointers need a "this" pointer
WorldEditor myWorldEditor;
int myInt = 42;
//map a string to the CreateEnvironment<Coin> function
std::map<std::string, CreateEnvironmentPtr> listEnv;
listEnv["test"] = &WorldEditor::CreateEnvironment<Coin>;
// call the member function pointer using the instance I created, as well as
// the mapped function
(myWorldEditor.*listEnv["test"])(myInt, false);
// (printing member value to cout to show it worked)
std::cout << (myWorldEditor.*listEnv["test"])(myInt, false)->i << std::endl; // prints 1
Live Demo
Solution 2: use std::bind and std::function
Perhaps we already know the parameters to the member function call at the time we create the entry for map. Using std::bind with a std::function will help us achieve that (Similar to Richard Hodges' solution):
// now our "function pointer" is really just a std::function that takes no arguments
using CreateEnvironmentPtr = std::function<std::unique_ptr<Environment>(void)>;
//declare an object of type WorldEditor, because member function pointers need a "this" pointer
WorldEditor myWorldEditor;
int myInt = 42;
//map a string to that function pointer
//ensure it gets called with the right args
// by using std::bind (which will also make the arg list appear the be void at call time)
// note that std::bind needs an instance of the class immediately after
// listing the function it should be binding
// only afterwards will we then pass the int& and bool
std::map<std::string, CreateEnvironmentPtr> listEnv;
listEnv["test"] = std::bind(&WorldEditor::CreateEnvironment<Coin>, &myWorldEditor, myInt, false);
// the mapped function
listEnv["test"]()->i;
// (printing resulting unique_ptr<Environment>'s member to cout to show it worked)
std::cout << listEnv["test"]()->i << std::endl; // prints 1
Live Demo 2
So I'm still rather new to programming/C++, and still trying to wrap my head around pointers and passing by reference and everything. A program I'm trying to figure out now needs to pass an array of structs to another function. I've gotten it working by just passing the array directly there. It seems to work fine. However, what I'm concerned about is that I believe I'm passing it by value, and I understand that it's better to pass structs by reference, so you're not making a copy of the struct every time...
Anyway, here's a basic example of what I'm doing:
struct GoldenHelmet {
int foo;
string bar;
};
void pass (GoldenHelmet ofMambrino[], int size);
int main () {
GoldenHelmet ofMambrino[10];
int size = sizeof(ofMambrino) / sizeof(ofMambrino[0]);
ofMambrino[1].foo = 1;
pass(ofMambrino, size);
cout << ofMambrino[2].foo << endl;
return 0;
}
void pass (GoldenHelmet ofMambrino[], int size) {
ofMambrino[2].foo = 100;
ofMambrino[2].bar = "Blargh";
}
From what I understand, it works because arrays are already pointers, right? But the way I have that configured, am I still passing a copy of the struct and everything to the pass() function? I've tried to pass it by reference, but it doesn't seem to want to work any way I've tried.
The C++ way:
#include <array>
typedef std::array<GoldenHelmet, 10> Helmets;
void pass(Helmets &);
int main()
{
Helmets h;
h[1].foo = 1;
pass(h);
//...
}
void pass(Helmets & h)
{
h[2].foo = 100;
// ...
}
Indeed, we pass the array by reference.
This syntax:
void pass (GoldenHelmet ofMambrino[], int size)
is actually quite confusing. Because you are not passing an array, you are passing a pointer. They are not the same thing though, don't get confused. This oddity only applies to function parameters. The above is exactly identical to this:
void pass (GoldenHelmet * ofMambrino, int size)
It's actually impossible to pass an array by value, unless it is a sub-object of another object. You can pass them by reference, you need to include the size though, but you can do that using a template:
template<int N>
void pass (GoldenHelmet (&ofMambrino)[N])
These are all possible, but none of them are pass by value. Just think of ofMambrino as being the address of the beginning of the array, and that is what you are passing.
void pass (GoldenHelmet ofMambrino[], int size)
void pass (GoldenHelmet ofMambrino[10], int size)
void pass (GoldenHelmet *ofMambrino, int size)
void pass (GoldenHelmet (&ofMambrino)[10], int size)
Arrays are represented and passed as pointers, so you are not copying anything here. In contrast, if you were passing a single struct, it would be passed by value.
Below is a code snippet to illustrate this last point:
void passByVal (GoldenHelmet ofMambrino) {
ofMambrino.foo = 100;
ofMambrino.bar = "Blargh";
}
void passByRef (GoldenHelmet& ofMambrino) {
ofMambrino.foo = 100;
ofMambrino.bar = "Blargh";
}
int main() {
GoldenHelmet h;
passByVal(h); // h does not change
passByRef(h); // fields of h get assigned in the call
}
First of all array is not pointers. We refer this as a pointer in the argument list because when we use
int x[ ]
x is actually const pointer that points the beginning of the array. And when you pass this to a function you send the adress of the memory that is beginning of the array. Thats why when you make a change in your function, you make change in the adress of your variable in the caller section actually. This is actualy simulated call by reference not call by reference. But effect is same with call by reference because you are working on memory locations. For this reason when you send array of your struct you pass actually adress of your array of structs. Thats why when you change value on this, you actually change your structs.
To use call by reference, one thing you must to do is to define your function prototype like
void f(int ¶m)
and when calling function, it is same with the others.
To summarize:
int main()
{
int x;
// simulated call by reference that use adress of variable,
// lets say adress of x is 19ff
f(&x); // actually you send 19ff
f(x); // call by reference that use reference of variable
}
// simulated call by reference
void f(const int *y)
{
// when you use like *y=10, you are writing on memory area 19ff, you actually
// change memory area that is belong to x in the main
}
// call by reference
void f(const int &y)
{
}