tags:

views:

911

answers:

3

What is the point of them?
I've never used them for anything, and I can't see myself needing to use them at all.
Am I missing something about them or are they pretty much useless?

EDIT: I don't know much about them, so a description about them might be necessary...

+4  A: 

Bind a pointer to a function is very useful in a variety of situations. Basically, it allows you to refer to functions as variables, which lets you choose, at runtime, which function you will call.

One use for this is in "callbacks". Say I want some background process to work for a while, and let us know when it's done (so we can update the GUI, or something). But sometimes, we may want this background process to call one method, and sometimes, we want it to call a different method. Rather than writing two versions of this background process, we can write it so that the background process receives a pointer to the function we want it to "call back". Then, when the process is finished, it calls whichever function it was given in the first place.

Basically, it just lets you have a heap more flexibility in deciding which method to call. In that way, it's quite similar to polymorphism. In fact, behind the scenes, I believe C++ uses pointers to functions to facilitate polymorphism (by storing a different table of pointers to functions for each class)

Smashery
+1  A: 

If I understand your question correctly. Why not?

struct test
{
    test* operator->() 
    { 
        std::cout << "test::operator->";
        return this; 
    }
};

test tt;
boost::bind( &test::operator ->, _1 )( tt );
bb
My question was more about, what are those operators, and not so much as what are the alternatives to using the operators.
DeadHead
+8  A: 

A PMF (pointer to member function) is like a normal (static) function pointer, except, because non-static member functions require the this object to be specified, the PMF invocation syntax (.* or ->*) allow the this object to be specified (on the left-hand side).

Here's an example of PMFs in use (note the "magic" line with the .* operator being used: (lhs.*opit->second)(...), and the syntax for creating a PMF, &class::func):

#include <complex>
#include <iostream>
#include <map>
#include <stack>
#include <stdexcept>
#include <string>

namespace {
    using std::cin; using std::complex; using::std::cout;
    using std::invalid_argument; using std::ios_base; using std::map;
    using std::stack; using std::string; using std::underflow_error;

    typedef complex<double> complexd;
    typedef complexd& (complexd::*complexd_pmf)(complexd const&);
    typedef map<char, complexd_pmf> opmap;

    template <typename T>
    typename T::reference top(T& st) {
        if (st.empty())
            throw underflow_error("Empty stack");
        return st.top();
    }
}

int
main()
{
    opmap ops;
    ops['+'] = &complexd::operator+=;
    ops['-'] = &complexd::operator-=;
    ops['*'] = &complexd::operator*=;
    ops['/'] = &complexd::operator/=;

    char op;
    complexd val;
    stack<complexd> st;

    while (cin >> op) {
        opmap::const_iterator opit(ops.find(op));
        if (opit != ops.end()) {
            complexd rhs(top(st));
            st.pop();
                                        // For example of ->* syntax:
            complexd& lhs(top(st));     // complexd* lhs(&top(st));
            (lhs.*opit->second)(rhs);   // (lhs->*opit->second)(rhs);
            cout << lhs << '\n';        // cout << *lhs << '\n';
        } else if (cin.unget() && cin >> val) {
            st.push(val);
        } else {
            throw invalid_argument(string("Unknown operator ") += op);
        }
    }
}

It's a simple RPN calculator using complex numbers instead of real numbers (mostly because std::complex is a class type with overloaded operators). I've tested this with G++; your mileage may vary with other platforms.

Input should be of the form (0,1). Spaces are optional, but can be added for readability.

Chris Jester-Young
The code has _no_ error checking, but I hope you get the idea anyway. :-D
Chris Jester-Young
Yeah, it makes sense. Thanks for the example.
DeadHead
Updated my version to actually add some error checking, because getting segfaults on an empty stack really bugged me. :-)
Chris Jester-Young