boomerang
boomerang

Reputation: 309

Initializing array of structures with function pointer member in C++

I am having trouble in initializing an array of structures with a function pointer as a member in it.

class Record
{
    private:
    typedef void (*display_fn_t) ();
    struct record {
        int a;
        display_fn_t disp;
    };
    static const record rec[];

    void disp1() { cout << "Display 1 with a string to display" << endl; }
    void disp2() { cout << "Display 2 with an integer to display" << endl; }

    public:
    int find() { /* logic to find the record comes here */ }
    void display() {
        for (int i = 0; i < 2; i++) {
            rec[i].disp();
        }
    }
}

const Record::record Record::rec[] = {
    { 10, disp1 },
    { 11, disp2 }
};

int main()
{
    Record r;
    if (r.find())
        r.display();
    return 0;
}

When I compile the above code, I am getting the following compilation error:

mca_record.cpp:56: error: argument of type ‘void (Record::)()’ does not match ‘void (*)()’

Upvotes: 0

Views: 932

Answers (2)

WhozCraig
WhozCraig

Reputation: 66194

Your syntax is wrong and isn't using the appropriate operators.

Fixing a multitude of syntax errors, and stripping out the unrelated find operation, then utilizing proper member function pointers and operator ->* gives the following (one of several ways to do this):

#include <iostream>

class Record
{
private:
    typedef void (Record::*display_memfn_t)();
    struct record
    {
        int a;
        display_memfn_t disp;
    };

    static const record rec[];

    void disp1() { std::cout << "Display 1 with a string to display" << std::endl; }
    void disp2() { std::cout << "Display 2 with an integer to display" << std::endl; }

public:
    void display();
};

const Record::record Record::rec[] =
{
    { 10, &Record::disp1 },
    { 11, &Record::disp2 }
};

void Record::display()
{
    for (size_t i=0; i<sizeof rec/sizeof*rec; ++i)
        (this->*(rec[i].disp))();
}

int main()
{
    Record r;
    r.display();
    return 0;
}

Output

Display 1 with a string to display
Display 2 with an integer to display

Compare it to your existing code, and not in particular that pointers to member functions are not simply pointers to functions. They require different handling and generally different operators to utilize. See here for different methods of member access (both variable and function).

Best of luck.

Upvotes: 1

marom
marom

Reputation: 5230

To make the call work you must invoke it like this:

        for (int i = 0; i < 2; i++) {
            (*rec[i].disp)();
        }

And initialize the table this way:

const Record::record Record::rec[] = {
    { 10, &Record::disp1 },
    { 11, &Record::disp2 }
};

Upvotes: 1

Related Questions