[英]Tables of C++ member functions
我需要一個將代碼映射到C ++成員函數的表。 假設我們有這個類:
class foo
{
bool one() const;
bool two() const;
bool call(char*) const;
};
我想要的是這樣的一張桌子:
{
{ “somestring”, one },
{ ”otherstring”, two }
};
這樣,如果我有一個foo
對象f
, f.call(”somestring”)
將在表中查找“ somestring”,調用one()
成員函數,然后返回結果。
所有被調用的函數都具有相同的原型,即它們是const,不帶參數並返回bool。
這可能嗎? 怎么樣?
是的,可以使用指向成員語法的指針 。
使用您提供的原型,地圖就可以了。
std::map< std::string, bool( foo::*)() const>
將使用這種語法來調用
this->*my_map["somestring"]();
看起來很奇怪的->*
運算符用於指向成員函數的指針,由於繼承,它們可能具有一些奇怪的注意事項。 (不只是原始地址,正如->
所期望的那樣)
是。
struct foo_method
{
std::string name;
bool (foo::*pfun)() const;
};
foo_method methodTable[] =
{
{ “somestring”, &foo::one },
{ ”otherstring”, &foo::one }
};
void foo::call(const char* name) const
{
size_t size = sizeof(methodTable)/sizeof(*methodTable);
for(size_t i = 0 ; i < size ; ++i)
{
if ( methodTable[i].name == name )
{
bool (foo::*pfun)() const = methodTable[i].pfun;
(this->*pfun)(); //invoke
}
}
}
我會使用帶有std::map
boost::function
。 具體來說,是這樣的:
typedef boost::function<bool()> MyFunc;
typedef std::map<std::string, MyFunc> MyFuncMap;
然后,給定MyFuncMap的實例,您可以執行map["something"]()
。 然后,您可以將其包裝在一個重載operator()
的類中。 您可以使用函數指針/引用,但是我更喜歡使用boost::function
因為它允許我將指針綁定到成員函數(使用boost :: bind)或使用其他函數對象。 您也可以像使用常規函數指針一樣在條件條件下測試boost::function
。
以下是相關文檔:
祝好運!
編輯:關於您的const成員和boost::function
,這是一個示例:
#include <boost/function.hpp>
#include <boost/bind.hpp>
typedef boost::function<bool ()> FuncPtr;
struct Test
{
bool test() const
{
std::cout << "yay" << std::endl;
}
};
int main(int argc, char **argv)
{
Test t;
FuncPtr ptr = boost::bind(&Test::test, &t);
ptr();
}
由於您只需要存儲具有相同參數和返回類型的相同類的成員,因此可以使用指向成員函數的指針:
bool foo::call(char const * name) const {
static std::map<std::string, bool (foo::*)() const> table
{
{"one", &foo::one},
{"two", &foo::two}
};
auto entry = table.find(name);
if (entry != table.end()) {
return (this->*(entry->second))();
} else {
return false;
}
}
這使用了C ++ 11的新初始化語法。 如果您的編譯器不支持它,則還有其他各種選擇。 您可以使用靜態函數初始化地圖:
typedef std::map<std::string, bool (foo::*)() const> table_type;
static table_type table = make_table();
static table_type make_table() {
table_type table;
table["one"] = &foo::one;
table["two"] = &foo::two;
return table;
}
或者你可以使用Boost.Assignment :
static std::map<std::string, bool (foo::*)() const> table =
boost::assign::map_list_of
("one", &foo::one)
("two", &foo::two);
或者您可以使用一個數組,並使用std::find_if
(或一個簡單的for
循環,如果您的庫還沒有,則使用一個簡單的for
循環)查找條目,或者如果您確保對數組進行了排序,則使用std::binary_search
。
我只想補充一點,沒有成員類調用實例的成員函數指針是沒有意義的。 您所描述的情況是造成這種情況的原因(我想您知道這一點),但是在其他情況下,可能有必要在某種函子構造中使用指向其所對應實例的指針或引用來封裝函數指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.