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