3
我正在查看一些已移植且未能编译的代码。代码已经以类似'C'的方式编写,并且正在传递函数指针以便为对象设置特定的增变器。被填充的对象声明如下:将指针传递给函数时未知的隐式类型
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_; }
};
相当标准的东西。然后我们有我修剪为简洁一些有趣的功能:
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);
}
然后调用此方法如下:
Person* person = new Person;
setMem("Name", person, Person::name); // (1)
setMem("Age", person, Person::age); // (2)
的想法似乎是通过一个标签,对象和适当的增变器的地址。正在使用第三个参数的类型来让编译器选择要调用的重载,然后特定的重载获得一个合适的变量就绪,并调用传递它的函数作为参数来设置对象的值。
这处理旧的Solaris编译器。然而,当它编译于GCC,我会在点(1)
和(2)
故障:
error: no matching function for call to
'setMem(const std::string& label, Person* person, <unknown type>)'
它看起来像新的编译器将,比如说,Person::age
作为一个类型,而不是指向一个功能,无法解决超载。我正在改变代码使用函数对象,而不是直接指向函数。
我想知道是否有一种方法,调用代码可以保持这种状态(即没有明确说明函数所需的类型),因为我不能更改Person
类,并且理想地希望保持最低限度的变化。
谢谢你,是的,我得到一个干净的构建在GCC 4.1上有这个例子。然而,它不适用于我在GCC 3.2上创建的原始代码(因为客户机密性而重写),所以GCC变得更好或者有更微妙的事情发生 - 我怀疑后者。 – 2011-06-08 11:35:36