C++ Function Pointers as class member - c++

Well,
I typedef function pointer as :
typedef string(*t_arr[5])();
and then i create function in class as :
void initStringFunctionPointer(t_arr t_err);
and then i declared as :
void Register::initStringFunctionPointer(t_arr t_err)
{
t_err[0] = &getName;
t_err[1] = &getSurname;
t_err[2] = &getUsername;
t_err[3] = &getPassword;
t_err[4] = &getEmail;
}
but all of lines gives this error :
C:\Qt Projects\base\ClassProject_tmp\goinlib.cpp:20: error: ISO C++ forbids taking the address of an unqualified or parenthesized non-static member function to form a pointer to member function. Say '&Register::getName' [-fpermissive]
t_err[0] = &getName;
^
I don't know what to do, Any ideas ?
Edit :
It worked, static or doing type is succeed, thank you.

It tells you right in the error message:
Say '&Register::getName'
Once you do this you will probably discover that it's illegal anyway because you can't store a pointer-to-member-function in a regular function pointer. You'll need to change your typedef therefore, or else make getName() and the rest static. To change the typedef, try this:
typedef string(Register::*t_arr[5])();
Hopefully that's right, the array thing makes me a little uncertain; you might consider keeping the array part out of the basic typedef and adding it on elsewhere (on a second typedef or at the place of use).

Related

C++ pointer to member function not a function pointer

Let's say I have the following definitions:
class ScriptInterpreter {
public:
class cell;
typedef ScriptInterpreter::cell (ScriptInterpreter::*proc_t) (const std::vector<cell> &);
class cell {
public:
proc_t proc;
};
ScriptInterpreter::cell proc_add(const std::vector<cell> & c);
};
And the following code going on:
ScriptInterpreter::eval(ScriptInterpreter::cell cell, environment * env)
{
// ...
ScriptInterpreter::cell c;
c.proc = &ScriptInterpreter::proc_add;
return (c.*proc_)(exps);
}
At the line where I try to call the function pointer I get the error
error: called object type 'proc_t' (aka 'ScriptInterpreter::cell (ScriptInterpreter::*)(const std::vector<cell> &)') is not
a function or function pointer
When I add the * in front of the func so the line looks like this:
ScriptInterpreter::cell c = (proc_cell.*proc_)(exps);
it produces this:
error: use of undeclared identifier 'proc_'
I already looked at Callback functions in c++ and other problems of that kind, but nothing really gave me a hint what's wrong or provided any information about my error. I definitely don't have any names twice or something of that kind.
Also after reading what is an undeclared identifier error and how do i fix it I'm pretty sure I got everything alright.
So what am I doing wrong?
Edit: updated the code with real code instead of placeholder code
In order to call a member function through a pointer of pointer-to-member type, you have to use either operator .* or operator ->*. And on the left-hand side you have to specify the object for which you want to invoke that member function.
In your case an attempt to do that could look as follows
A::B b_object;
b_object.func = &A::func_to_call;
A a_object;
A::B other_b_object = (a_object.*b_object.func)();
Note that since the pointer is declared as pointing to a member of A, the .* operator need an object of type A on the left-hand side.
However, in your specific case this is ill-formed since b_object.func is private and no accessible from main.
P.S. int main, not void main.

Getting the address of an overloaded static function [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
how to specify a pointer to an overloaded function?
I have a library which has a class defined as:
struct ClassA
{
static ClassA foo(long);
static ClassA foo(double);
}
I need to get the addresses of both of those functions. The code I am currently trying gives error C2440: cannot convert from 'overloaded-function' to '...'
ns::ClassA (ns::ClassA::*ClassA_foo1)(long) = &ns::ClassA::foo;
ns::ClassA (ns::ClassA::*ClassA_foo2)(double) = &ns::ClassA::foo;
I thought it might be the fact that they are static, but placing static either before or after the return type gives the same error.
The fact that the function is overloaded is not really relevant. The real issue here is the difference between a function-pointer and a member-function-pointer. I'll run through some examples without overloading.
Solution: Either remove the static, in order to define them as member-functions. Or else replace ns::ClassA::*ClassA_foo1 with *ClassA_foo1. I think you want the latter. (But I actually recommend you use typedef, as others have already suggested).
Consider these two:
namespace ns {
struct ClassA
{
static ClassA foo(long);
};
}
and
namespace ns {
struct ClassA
{
ClassA foo(long);
};
}
In the former case, foo is static and is therefore a typical function, and can be stored in a function-pointer:
ns::ClassA (ClassA_foo1)(long) = &ns::ClassA::foo;
If you remove the static, then it is not a function any more, it's a member function. And pointers-to-member-functions are different from pointers-to-functions, they must be executed with an object that will be the this object on which the method is called.
The type of a function pointer includes the type of the return value and the type of the parameters. But the type of a pointer-to-member-function must also include the type of the this object - you wouldn't expect to be able to run a method from a Circle on an object of type BankAccount.
Declaring a pointer-to-function:
ReturnType (*variable_name) (PARAM1, PARAM2)
Declaring a pointer-to-member-function:
ReturnType (ThisObjectType::*variable_name) (PARAM1, PARAM2)
This last line is the interesting one. At first glance, you might think that R (A::*v) (P1,P2) declares a normal function-pointer and places the resulting variable v into the A scope. But it does not. Instead it defines a pointer-to-member-function which operates on objects of type A.
The problem that you are observing has absolutely nothing to do with the fact that the function is overloaded. You'd get the same error for a non-overloaded function.
Static member functions have ordinary function type. Meanwhile, you are trying to interpret them as functions of member-function type. This leads to pointer type mismatch reported to you by the compiler. Here's a simple example that will fail to compile for the very same reason
struct S {
static void foo();
};
...
void (S::*p)() = &S::foo; // ERROR, pointer type mismatch
In other words, your pointers are declared as pointers of pointer-to-member-function type. Such pointers cannot hold the address of a static member function. A static member function and a non-static member function are beasts of completely different nature. The corresponding pointer types are not compatible and not convertible to each other. That's the reason for your error.
This is how it was probably supposed to look
ns::ClassA (*ClassA_foo1)(long) = &ns::ClassA::foo;
ns::ClassA (*ClassA_foo2)(double) = &ns::ClassA::foo;
i.e. the pointers on the left-hand side should be declared as ordinary function pointers, not as member function pointers.
ns::ClassA (ns::ClassA::*ClassA_foo1)(long) = &ns::ClassA::foo;
ns::ClassA (ns::ClassA::*ClassA_foo2)(double) = &ns::ClassA::foo;
It looks like you are trying to set the pair of static members ClassA_foo1 and ClassA_foo2 at file scope. If so, this is not valid syntax. The syntax for defining a static member is
SomeType ClassName::member = initializer;
It's best to use a typedef to declare and define ClassA_foo1 and ClassA_foo2:
struct ClassA {
typedef ClassA (*ClassALongGenerator) (long);
typedef ClassA (*ClassADoubleGenerator) (double);
static ClassALongGenerator ClassA_foo1;
static ClassADoubleGenerator ClassA_foo2;
};
then at file scope in some source file
ns::ClassALongGenerator ClassA_foo1 = ns::ClassA::foo;
ns::ClassADoubleGenerator ClassA_foo2 = ns::ClassA::foo;

C++ class whose member is a struct: Cannot understand compiler error

I want to create a class one of whose private: members is a struct point(see below). The public members ndim and numparticles are
set at run-time by the user, which are used to create corresponding arrays inside the class . However I am getting a compiler error. I don't understand where I messed up.
The compiler error being displayed:
nbdsearch.h:25: error: ‘point’ does not name a type
nbdsearch.h:24: error: invalid use of non-static data member ‘nbdsearch::ndim’
nbdsearch.h:31: error: from this location
nbdsearch.h:31: error: array bound is not an integer constant before ‘]’ token
The class code:
class nbdsearch{
public:
int ndim,numparticles;
point particlevec[numparticles];
private:
struct point{
string key;
double cood[ndim];
};
};
nbdsearch.h:31: error: array bound is not an integer constant before ‘]’ token
double cood[ndim];
Array size needs to be a compile time constant and ndim clearly isn't. ndim is a variable.
error: ‘point’ does not name a type
point particlevec[numparticles];
On line 25, compiler doesn't know what point is. The structure is defined at a later point. Compilers in C++ work on a top to bottom approach(Not sure whether C++0X relaxes this rule). So, what ever types being used should be known to it before hand.
Try this -
class nbdsearch{
private:
struct point{
string key;
std::vector<double>cood;
};
public:
int ndim,numparticles;
std::vector<point> particlevec;
};
point needs to be declared before its use. Try putting the private: block before the public: block.
There are a few different problems with your code.
The declaration of point needs to be visible to compiler before
you use it
You're trying to create array from variables that are not compile time constants; C++ does not allow creation of variable length arrays.
To fix these problems:
Move the declaration block for point above where you use it. Note that since the definition of point is private, someone calling nbdsearch::particlevec will not be able to store that value. All they could do is pass it along to another member function (or friend function) of nbdsearch.
Change declaration of particlevec to std::vector<point> particlevec. Make a similar change for point::cood. Once the user specifies values for ndim & numparticles use std::vector::resize to size the arrays appropriately.

copying pointer to member functions from a structure

I have my code organized as following
class MyClass
{
public:
typedef void (MyClass::Ptr2func)();
}
struct abc
{
MyClass::Ptr2func ptr;
bool result;
}
void main()
{
MyClass myCls;
abc var;
//here is a lot of decision making code and pointer initializations
//I want to copy the pointer to function in another variable
MyClass::Ptr2func tempPtr;
tempPtr=var.ptr;
}
When I try to copy the var.ptr into tempPtr it gives me a compilation error that the argument list is missing. Also it gives me compilation error on myCls.*(var.ptr()); Is there a precedence issue? I have tried using parenthesis but nothing works. I hope someone can help me out on this.
Thanks and regards,
Saba Taseer
I believe that the problem is that your typedef
typedef void (MyClass::Ptr2func)();
Is not defining a typedef for a pointer to member function, but for a member function type. The typedef for a member function pointer would be
typedef void (MyClass::* Ptr2func)();
Notice the explicit pointer involved here. The type
typedef void (MyClass::Ptr2func)();
is actually a typedef for the type of a member function inside of MyClass that takes no arguments and returns void.
As for your final question, the proper syntax for calling a pointer to a member function is (I believe)
(myCls.*var.ptr)()
Notice that you must parenthesize the expression (myClass.*var.ptr) before trying to call it as a function, since the code
myCls.*(var.ptr())
Means "dereference the pointer-to-member returned by var.ptr() relative to object myCls.
Hope this helps!
This:
typedef void (MyClass::Ptr2func)();
defines a function type. The MyClass:: is completely extraneous in that definition; the final type is void (). (Why? You're in MyClass, so MyClass:: is treated as reinforcement that you want the typedef Ptr2func to belong to MyClass, not as a statement that you want the type to designate a member function.)
You want this:
typedef void (MyClass::*Ptr2func)();
which defines a pointer to a member function.
You're asking about compilation errors.
As I'm writing this your code does not have semicolong after each class definition.
Also, just about any other compiler than MSVC will react to void main; use standard int main.
As an utter beginner (making those kinds of mistakes) it's not a good idea to use member pointer.
Simply don't, but instead explain what you hoped to achieve by that.
Cheers & hth.

c++ scoping weirdness - Why do inner-type parameters of member functions do not need scoping?

Let's say we're given this class with an inner struct.
class Some {
public:
struct Crap{};
Crap Process(Crap& c);
}
Some::Crap Some::Process(Crap& crap) { Crap moreCrap = .. }
It makes sense to me that the return type (Some::Crap) in "Process" is scoped.
It makes sense to me that no scoping is needed inside the body of "Process".
I do not understand why the inner struct parameter of Process (Crap& crap) does not require scoping.
Does anyone have any insight on this?
Thanks
In fact, the parameter type does need to be qualified (unless your example is incorrect and you intend for Process to be a member function of Some).
Assuming the following snippet:
class Some
{
public:
struct Crap{};
Crap Process(Crap&);
};
Some::Crap Some::Process(Crap& crap) { ... }
Basically, Crap does not require scoping inside the function parameter list and body for the same reason you don't need this-> to access data members and member functions: it is implicit because it is at the same scope.
The reason return type is needed is simply because the parser encounters the return type before the method name and cannot (is not required to?) deduce scope at that moment.
The question title says 'member function', but your example contains no member function. Assuming you meant Some::Process rather than just Process:
The class scope for the member function definition begins at the (, not at the {. I assume the reasoning is exactly so that things like this can be typed shorter.