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();
Related
I have currently defined a function pointer and to me it seems like the function matches the definition, however I am getting an error:
1 IntelliSense: a value of type "std::string (RSSCrawler::)(const web::json::value &headlines)" cannot be assigned to an entity of type "std::string ()(const web::json::value &headlines)"
I am not sure what is wrong, but here is my code
string(*GetHeadline)(const value&headlines);
GetHeadline = Extract;
string RSSCrawler::Extract(const value &headlines)
{
return "";
}
The compiler explained this with a type mismatch error and showing the difference in the first set of parentheses. You need a member function pointer. That is a separate type from a 'plain'/free function pointer. (static member functions act like free functions in this sense, but that's not what you have.)
You can find plenty tutorials about these, but here's a quick reference. (I have to restrain myself not to de-capitalise these function and variable names because it just looks wrong, even without SO's auto-formatting.)
// Declare pointer-to-member-function of a given class and signature
std::string (RssCrawler::* GetHeadline)(const value&);
// Bind it to any method of the same class and signature
GetHeadline = &RssCrawler::Extract;
// Call it on a given instance of said class
std::cout << (someInstance.*GetHeadline)(someValue) << std::endl; // operator .*
Or you can do this to get a const initialised pointer, though I think that defeats the purpose of a function pointer, except for const-correctness when declaring them as arguments to other functions...
std::string (RssCrawler::*const GetHeadline)(const value&) {
&RssCrawler::Extract
}
QString msgText = QString("The file has been saved at %1\sysconf.xml").arg(QApplication::applicationDirPath);
gives me the above error. I used .arg() before, so I wonder why it gives me this error? All my other .arg() in my code works properly.
THE EXPLANATION
QApplication::applicationDirPath is a static member function, to get the value you are looking for you must treat it as such, hence; you must call the function.
Currently you are trying to pass a function pointer to QString::arg, and since the compiler cannot find a suitable overload for such construct it raises a diagnostic.
THE SOLUTION
QString msgText = QString(...).arg(QApplication::applicationDirPath ());
Note: See the added () after QApplication::applicationDirPath.
Try actually calling the function:
QString msgText = QString("The file has been saved at %1\sysconf.xml").arg(QApplication::applicationDirPath());
Notice the "()" after applicationDirPath.
According to this you are passing a pointer to the static member function applicationDirPath, and arg has several overloads that all do not accept such a poitner. It seems your compiler finds several conversions of the function pointer to the parameter types arg is overloaded for and gets confused. Did you mean this:
QString msgText = QString("The file has been saved at %1\sysconf.xml")
.arg(QApplication::applicationDirPath());
// ^^--!!
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.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is the return type part of the function signature?
Following up on a related but tangential question ( How to disambiguate function templates that differ only by return type? ), I would like to ask a question related to the fact that the return type of a function is not considered to be part of the signature of a function.
Consider the following code:
#include <iostream>
int foo()
{
return 0;
}
int main()
{
long n = static_cast<long(&)()>(foo)(); // Error: incorrect return type
int p = static_cast<int(&)()>(foo)(); // Compiles just fine
}
The line of code noted above results in a compilation error, because the return type of the function type to which foo is being cast does not match the return type of the function foo.
But I thought the return type of a function does not play a role in the signature of the function!
According to a certain line of thinking, since the function signature long(&)() matches the signature of foo, the cast of foo to a function of this type should succeed.
However, the cast does not succeed. Where does the reasoning go wrong? If the cast cannot fail due to the function signature, then why does the cast fail?
You're correct that the return type doesn't form part the signature of the function.
However, it does form part of the type of the function, and you're not allowed to convert pointers to incompatible function types.
The return type is part of the type, although not used for overload resolution. It is important not to confuse the terms. Basically, the type includes arguments and return value, but during overload resolution, the return type is not considered. The type of the function or function pointer is a contract between the caller and the callee, and they must fully agree on the terms.
From a practical point of view, consider what would happen if what you suggest was allowed. Imagine a calling convention in which the caller reserves space and passes a pointer to that space to the function, the function will then construct in that location the returned object (this is actually a very common calling convention). Consider now that you were allowed to perform the cast you proposed and the following use case
static_assert(sizeof(T1)<sizeof(T2));
T2 f();
T1 (*p)() = &f;
p(); // call
Now when the compiler is processing p() it reserves space somewhere, and given the type of the function it needs to reserve sizeof(T1). It then calls the function, which ends up calling f which writes sizeof(T2) bytes into the location causing an overflow.
Even if the sizes matched, the code would be problematic. Consider T1==int and T2==float in a platform where sizeof(int)==sizeof(float). While the code above would not cause a buffer overrun, the bitpattern stored in the location of the return type would be that of a float, not that of an int.
The return type of a function is not part of the signature, but the signature isn't what the compiler needs to know in order to correctly call the function referred to by a function pointer or reference.
As well as the parameters, the compiler needs to know the return type, so that it can make space for the return value on the stack, or read the return value from the correct register(s), or whatever the calling convention demands in a given implementation.
That is why the return type is part of the type of the function -- so that the type tells the compiler what it needs to know at compile time in order to emit code to call the function.
the function signature long(&)() matches the signature of foo
long(&)() isn't a function signature, it's a type. foo(void) is a (representation of a) function signature. It includes the name and parameters. But you never need to specify a function signature in C++ code (well, perhaps as a string passed to dlsym or similar). The definitive representation of a function signature is the mangled name of the function in a given implementation. The mangling scheme isn't standard, it's up to the implementation (although if different implementations want to call into each other's libraries then they must use the same scheme, so the OS might specify one).
The return type of a function is considered part of its signature (and of its type). However, it is allowed to assign function pointers to variables with different return types if the return types are "covariant".
I have a legacy function that looks like this:
int Random() const
{
return var_ ? 4 : 0;
}
and I need to call a function within that legacy code so that it now looks like this:
int Random() const
{
return var_ ? newCall(4) : 0;
}
The problem is that I'm getting this error:
In member function 'virtual int Random() const':
class.cc:145: error: passing 'const int' as 'this' argument of 'int newCall(int)' discards qualifiers
Now I know in order to fix this error I can make my newCall() a const function. But then I have several funciton calls in newCall() that I have to make, so now I would have to make all of those function calls const. And so on and so forth until eventually I feel like half my program is going to be const.
My question: is there any way to call a function within Random() that isn't const? Or does anyone have any ideas on how to implement newCall() within Random() without making half my program const.
Thanks
-josh
int Random() const
{
return var_ ? const_cast<ClassType*>(this)->newCall(4) : 0;
}
But it's not a good idea. Avoid if it's possible!
you should alter your program to use/declare const correctly...
one alternative is to use const_cast.
const_cast<MyClass *>(this)->newCall(4)
Only do this if you're certain newCall will not modify "this".
There are two possibilities here. First, newCall and ALL of its callees are in fact non-modifying functions. In that case you should absolutely go through and mark them all const. Both you and future code maintainers will thank you for making it much easier to read the code (speaking from personal experience here). Second, newCall DOES in fact mutate the state of your object (possibly via one of the functions it calls). In this case, you need to break API and make Random non-const to properly indicate to callers that it modifies the object state (if the modifications only affect physical constness and not logical constness you could use mutable attributes and propagate const).
Without using const casts, could you try creating a new instance of the class in the Random() method?
The const qualifier asserts that the instance this of the class will be unchanged after the operation, something which the compiler cant automagically deduce.
const_cast could be used but its evil
if it's really a random number generator, then the number generation code/state could likely be placed in a class-local static generator. this way, your object is not mutated and the method may remain const.