开发者

Implicit type unknown when passing pointer to function

I'm looking at 开发者_如何学Csome code at the moment which has been ported and is failing to compile. The code has been written in a rather 'C' like way and is passing function pointers in order to set particular mutators on an object. The object being populated is declared as follows:

class Person
{
    std::string n_;
    int a_;

    public:
        void name( const std::string& n ) { n_ = n; }
        std::string name() const { return n_; }
        void age( const int& a ) { a_ = a; }
        int age() const { return a_; }
};

Fairly standard stuff. Then we have some interesting functions which I've trimmed for brevity:

typedef void (Person::FnSetStr)(const std::string& s);
typedef void (Person::FnSetInt)(const int& i);

void setMem( const std::string& label, Person* person, FnSetStr fn)
{
    // Do some stuff to identify a std::string within a message from the label.
    // assume that 'val_s' contains the string value of the tag denoted by
    // the label.
    (person->*fn)(val_s);
}

void setMem( const std::string& label, Person* person, FnSetInt fn)
{
    // Do some stuff to identify an int within a message from the label.
    // assume that 'val_i' contains the int value of the tag denoted by the
    // label.
    (person->*fn)(val_i);
}

And then this gets called as follows:

Person* person = new Person;
setMem("Name", person, Person::name );   // (1)
setMem("Age", person, Person::age );     // (2)

The idea seems to be to pass a label, an object and the address of an appropriate mutator. The type of the 3rd parameter is being used to get the compiler to select which overload to call and the specific overload then gets a suitable variable ready and calls the function passing it as a parameter to set the value on the object.

This workled on an old Solaris compiler. However, when it compiles on GCC, I get failures at points (1) and (2):

error: no matching function for call to
    'setMem( const std::string& label, Person* person, <unknown type> )'

It looks like the new compiler treats, say, Person::age as a type rather than a pointer to a function and cannot resolve the overload. I am looking at changing the code to use a function object rather than straight pointers to functions.

I wanted to know whether there's a way that the calling code can stay like this (i.e. without an explicitly stating the type that the function takes) bearing in mind that I can't change the Person class and would ideally like to keep changes to a minimum.


First change the declaration:

typedef void (Person::*FnSetStr)(const std::string& s);
typedef void (Person::*FnSetInt)(const int& i);

Then change the call:

setMem("Name", person, &Person::name );   // (1)
setMem("Age", person, &Person::age );     // (2)

Builds clean at warning level 4 in VS 2010.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜