简体   繁体   中英

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 (*)()'

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 }
};

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM