This is a follow up question to my previous post: C++: Initializing Struct and Setting Function Pointer
My new question is how do I call a pointer-to-member function within a struct? I have modified my previous code to:
float MyClass::tester(float v){
return 2.0f*v;
}
struct MyClass::Example{
float(Scene_7::*MyFunc)(float);
float DoSomething(float a){
return (MyFunc)(a); //ERROR, SEE BELOW FOR OUTPUT
}
};
I then set the function as follows, and output the result to the call:
struct Example e;
e.MyFunc = &MyClass::tester;
std::cerr << e.DoSomething(1.0f) << std::endl;
I get the following error: must use '.' or '->' to call pointer-to-member function...
The problem is I don't know how to do this. I am guessing I have to call something like this->*(myFunc)(a) within DoSomething but this references the struct. I have tried searching "this within struct pointer-to-member function" but have not been able to find anything. Any help or suggestions would be great. I feel like I am close but it is just a matter of syntax at this point.
The operator precedence of .* and ->* is, IMHO, broken. You need to wrap the operands in parentheses in order to call.
return (this->*MyFunc)(a);
Otherwise, the compiler thinks you're doing this->*(MyFunc(a)), which is obviously invalid.
Interestingly enough, (this->*MyFunc) as a standalone expression is also invalid. It needs to be called on the spot.
I cant tell if you have other errors, do to the lack of code, but you are calling a member function the wrong way, you call them like this:
return (obj->*MyFunc)(6);
I am not sure if you can use this in place of obj on the line above, since from the declaration, you need a pointer to an object of type Scene_7, so you will need to know a pointer of the correct type at that spot in the code..
Remember that . operator has higher precedence than the * operator. So when dealing with pointes and structs etc you will need to use paranthesis or -> operator which means that the pointer points to what.
Related
I have some problems with referencing void pointer to class.
I created a node "index" with a void data pointer which point to a class "studentinfo";
however, I encountered problems when I was trying to extract data member of the class "studentinfo".
The output error message is saying:
"invalid type argument of unary '*' (have 'int')
int main()
{
...
Studentinfo *stu=new Studentinfo(id,name,score);
index=createNode(stu);
cout<<*static_cast <Studentinfo*> (index->dataPtr)->id; //Error ocurrs
...
}
-> already does a deference. So stu->id is the same as (*stu).id.
In your code you are actually trying to deference id, which is an int. This is why you get that error.
The -> operator dereferences a pointer and accesses it's member. The * also does this. Because you've included both, you're actually trying to do it twice.
Probably the correction to the code you're looking for probably just needs to remove the extra * dereference. The error you're getting is because static_cast <Studentinfo*> (index->dataPtr)->id is already fully dereferenced and returning what you want, id. id is an int, so the * dereference operator is attempting to dereference an id(an int) which gives the error invalid type argument of unary '*' (have 'int')
Now... with all that said I'm going to reiterate some of what your commentors have already said. This is extremely unsafe code. There's rarely a good reason to use void pointers or malloc in C++. Try to spend some more time learning about A: Constructors, B: How they interact with the new operator, and C: templates.
You will get code that is more readable and less error prone utilizing these techniques. Your main will be much more readable, as the statement that is currently giving you trouble can be simplified to cout<<index->dataPrt->id if your node uses templates, rather than a void pointer.
When I use the dereference operator on the pointer to class with overloaded opearator() (aka functors) - it works like a charm:
struct Functor {
int operator()(int a, float b) {
return a+b;
}
};
Functor g;
Functor * f = &g;
g(1,2.);
(*f)(1,.2);
f->operator()(1,2.f);
But the form
// f->(1,2.f); // doesn't compile (expected unqualified-id)
Why is that?
In C++, the dot (.) operator is used to access members and call methods on an object. In your example, you could have used in the following way:
g.operator()(1, 2.);
and it would have compiled fine. Instead, you call the operator in the equivalent (and more conventional) notation, as follows:
g(1,2.);
which is nice and clean. What you are trying to do is achieve the same clean operator call, but from a pointer, using the -> notation, thinking that the same magic will apply. Sadly, it does not work that way. In C++, p->a() is a shorthand for (*p).a(). It is, in other words, a way to
dereference a pointer -- *p;
call a method (or access a member) from that dereferenced object -- (*p).a();
That dereferenced object is no longer a pointer (the parenthesis around *p achieve that), which is why the dot operator can be called. So when you write:
f->(1,2.f);
what you are writing is something like:
(*f).(1, 2.f);
which is not valid C++ since (*f) does not represent an address to a Functor object. Note that:
f->operator()(1,2.f);
is valid because it means:
(*f).operator()(1, 2.f);
which works. It is equivalent to the first line I wrote above: g.operator()(1, 2.);.
Hope this helps.
I have a function like this:
int find_string ( string *url){
if(*url.find() != string::npos){
[...]
}
[...]
}
And call it this way:
find_string(&url);
But I got the following compiling error:
request for member ‘find’ in ‘url’, which is of non-class type ‘std::string*’
Why this happen and, most importantly, how can I fix this? (When there was no pointer, it was working)
*url.find() is equivalent to *(url.find()) when what you actually want is (*url).find(). Better yet you should be using url->find() instead.
The reason for this is the dereference (*) operator has lower precedence than the element selection (.) operator.
use (*url).find() or, better url->find()
*url.find tries call find() function and then use operator *
I have 2 classes CVKinectWrapper.cpp and main.cpp. In the CVKinectWrapper, in the bool CVKinectWrapper::update(){ ... i have a variable XnSkeletonJointPosition righthand; I would like to access this variable in the main.cpp class. therefor i have created a
`void CVKinectWrapper::getRightHand(XnSkeletonJointPosition *righthand){
//*righthand = righthand;
righthand->copyTo(*righthand);
}`
The direct assignment doesn't work, i get this error = 'No match for 'operator=' in*righthand=righthand'.
The copyTo doesnt work because the datatype of righthand hasn't got this method.
For extra info :
This is how i access the wrapper in the main class = CVKinectWrapper *wrapper = CVKinectWrapper::getInstance();
wrapper->getRightHand(XnSkeletonJointPosition *righthand)
My question now is how can i access the righthand variable from the CVKinectWrapper in the main class.
This is probably a very basic question but i'm rather new to c++.
Thanks in advance.
When asking about compiler errors, it is usually a good idea to provide the exact error message, which in this case it probably states what the types of the two arguments are. At any rate, I think I can guess what the problems are.
You mention that you have a variable named righthand, which I assume is actually a member of the class, and you want to copy the value to a different variable passed to the function getRightHand. Now the problem is that the argument of the function has the same name as the member, and it is shadowing it. Inside getRightHand, the identifier righthand refers to the argument, not to the member. You can solve this by either changing the name of the argument or qualifying the access to the member: *righthand = this->righthand;
As of the particular error message, the operation *righthand = righthand; literally means assign the value of the pointer righthand (argument to the function) to the object that it points, which does not make much sense. From a design point of view, the function as it is is quite un-idiomatic in C++, and should probably be replaced by:
const XnSkeletonJointPosition& CVKinectWrapper::getRightHand() const {
return righthand;
}
And the caller would do:
XnSkeletonJointPosition res = wrapper.getRightHand();
i have a question about the function call in the following example:
int main()
{
int a, b;
cin >> a >> b >> endl;
cout << *f(a,b);
return 0;
}
So is *f(a,b) a valid function call?
Edit:: sorry for the errors, i fixed them now i'm a little tired
The code at least could be reasonable. For it to work, f must be defined as a function that returns either of two sorts of things: either it returns a pointer, in which case the * dereferences the pointer, so whatever it was pointing at gets sent to standard output. Otherwise, f must return some user-defined type that defines operator * to return something that's compatible with cout.
Whatever f is, *f(a, b) attempts to apply the indirection operator to the result of f(a, b).
If f is a function pointer and you're trying to call it, while you could do this:
(*f)(a, b)
Just doing f(a, b) is simpler.
I don't think there is any way to tell without seeing the definition of f. C++ requires a lot of context to know what is going on.
It is very tough to tell if it is valid or not without knowing what 'f' is. But if it returns something that can be dereferenced it looks fine as long as that 'dereferenced' value can be printed (an overloaded operator <<) should exist for the type.