0

I'd like to use a pointer to member function in C++, but it doesn't work:

pointer declaration:

int (MY_NAMESPACE::Number::*parse_function)(string, int);

pointer assignation:

parse_function = &MY_NAMESPACE::Number::parse_number;

This call works perfectly (itd is an iterator to elements of a map):

printf("%s\t%p\n",itd->first.c_str(),itd->second.parse_function);

But this one doesn't work:

int ret = (itd->second.*parse_function)(str, pts);
$ error: 'parse_function' was not declared in this scope

And this one neither

int ret = (itd->second.*(MY_NAMESPACE::Number::parse_function))(str, pts);
$ [location of declaration]: error: invalid use of non-static data member 'MY_NAMESPACE::Number::parse_function'
$ [location of the call]: error: from this location

I don't understant why ...

Thx in advance !!

Jav
  • 1,445
  • 1
  • 18
  • 47
  • 2
    Might be better to familiarise yourself with std::function – goji Nov 30 '12 at 09:14
  • Please show the declaration of `parse_number` and of the container to which `itd` belongs. – Angew is no longer proud of SO Nov 30 '12 at 09:21
  • the first call (in the printf) returns something coherent (there is a switch case where a parsing_function is affected to "parse_function" and. All the elements of the map that match case1 the printed result is 0x2ad9d65302e0 and all the elements that match case2 the printed result is 0x2ad9d65303b0. – Jav Nov 30 '12 at 09:22
  • Tried removing the asterisk in `int ret = (itd->second.*parse_function)(str, pts);` ? – peterph Nov 30 '12 at 09:22
  • Please post a complete example that shows your problem. With function pointers in C++, the devil is in the details and they become much more obvious to us if you post a complete example. – Bart van Ingen Schenau Nov 30 '12 at 09:26
  • $ error: must use '.*' or '->*' to call pointer-to-member function in 'itd.std::_Rb_tree_iterator<_Tp>::operator-> [with _Tp = std::pair, MY_NAMESPACE::Number>, std::_Rb_tree_iterator<_Tp>::pointer = std::pair, MY_NAMESPACE::Number>*]()->std::pair, MY_NAMESPACE::Number>::second.MY_NAMESPACE::Number::parse_function (...)' – Jav Nov 30 '12 at 09:30
  • Try using `->*` then, what happens? It is a pointer after all. –  Nov 30 '12 at 09:32
  • 1
    Can you edit your question to include a [usable example](http://sscce.org/)? – Angew is no longer proud of SO Nov 30 '12 at 09:35
  • '->*' instead of '.*' doesn't change the error's message – Jav Nov 30 '12 at 09:47
  • question solved (see Olaf's post) – Jav Nov 30 '12 at 10:06

2 Answers2

1
int (MY_NAMESPACE::Number::*parse_function)(string, int);

This shows, parse_function is a pointer to a member function of class Number.

This call works perfectly (itd is an iterator to elements of a map):

printf("%s\t%p\n",itd->first.c_str(),itd->second.parse_function);

and from this we can see parse_function is a member of itd->second, whatever this is.

For this call

int ret = (itd->second.*parse_function)(str, pts);

or this call

int ret = (itd->second.*(MY_NAMESPACE::Number::parse_function))(str, pts);

to succeed, itd->second must be of type Number, which it presumably isn't. And parse_function must be defined as either a variable in the current or enclosing scope (fist case) or a static variable of class Number (second case).

So you need some Number and apply parse_function to that

Number num;
(num.*(itd->second.parse_function))(str, pts);

or with a pointer

Number *pnum;
(pnum->*(itd->second.parse_function))(str, pts);

Update:

Since itd->second is a Number, you must apply parse_function, which is a member of it, like this

int ret = (itd->second.*(itd->second.parse_function))(str, pts);
Olaf Dietsche
  • 72,253
  • 8
  • 102
  • 198
  • `itd->second` must be of type `Number`... but it is! `map::iterator itd = mapNumbers.begin();` Argh... I don't understand – Jav Nov 30 '12 at 09:53
  • @Jav Please include this *important* information in your question. – Olaf Dietsche Nov 30 '12 at 09:59
  • Thank you!!!! This works now! (omg:I haven't thaught about this but now it seems clear to me, txh) – Jav Nov 30 '12 at 10:05
0

You can define pointers to functions like so: type(*variable)() = &function; For example:

int(*func_ptr)();
func_ptr = &myFunction;

I might just not realize your code this early morning, but problem could be that parse_function is a pointer, yet you're calling it like itd->second.*parse_function. Pointers are called with the ->*, so try doing itd->second->parse_function.

Might not fix anything tho, I can't really seem to catch onto your code. Posting more information, it's hard to tell from two lines of code.


Here's one example on how it's used in actual code, this one calls func() through cb() using pointers and parameters only:

int func()
{
    cout << "Hello" << endl;
    return 0;
}

void cb(int(*f)())
{
    f();
}

int main()
{
    int(*f)() = &func;
    cb(f);
    return 0;
}