2012-09-27 34 views
0

問題C++ arbitary函數的反序列化

假設有一組不同的功能。每個函數都可以是某個對象的成員函數,並且可以採用任意數量的參數。爲了簡單起見,我們假設每個函數都有不超過8個參數int,doublestd::string類型。例如:

class MyClass{ 
public: 
    void DoA(int i); 
    void DoB(double d, int i); 
}; 

class YourClass{ 
public: 
    void DoC(std::string s); 
    void DoD(int i1, int i2, int i3); 
}; 

讓我們假設有一個文件包含一系列關於函數的記錄。每個記錄都包含要調用的函數的名稱,其參數值和用於成員函數的對象的指針。我需要一種方法來從文件中讀取所有這些數據,並以正確的參數以正確的順序執行函數。

例如,可以將函數的名稱硬編碼,但向函數庫中添加新函數應該儘可能簡單。

動機

這是roguelike遊戲項目的一部分,我想創造,特別是保存/載入遊戲系統。一旦玩家試圖保存他的遊戲,所有尚未發生的事件也必須被保存,並且下一次玩家加載遊戲事件應該被正確加載和計劃。由於roguelike顯然需要大量的空間來擴展,我不想對功能類型做任何假設。

+1

你爲什麼不只是使用一個序列化庫??? – 2012-09-27 21:31:45

+1

由於您沒有提出問題,因此很難回答。無論如何,這種設計是不好的;使用嵌入式腳本語言(我不是主張Lua,根本不是),忘記這個怪異的概念。或者合併到Gamedev SE,然後我會回答你。 –

+0

問題是如何實現這樣的事情。 @VladLazarenko我不知道任何這樣的庫,到目前爲止,我試圖用XML記錄保存。 – Saage

回答

1

這裏有一個想法:

class Foo 
{ 
    void f1_impl(double, char, int); 
    void f2_impl(int, int); 

    void func1(std::string s) 
    { 
     double d; 
     char c; 
     int i; 

     std::tie(d, c, i) = parse<double, char, int>(std::move(s)); 

     f1_impl(d, c, i); 
    } 

    void func2(std::string s) 
    { 
     // similarly 
    } 
}; 

std::unordered_map<std::string, void (Foo::*)(std::string)> const functions 
{ { "function1", &Foo::func1 }, 
    { "function2", &Foo::func2 }, 
}; 

輸入文件:

function1 1.250000,'a',2815 
function2 12,-80 
function2 99,111 

解析:

Foo x; 

for (std::string line; std::getline(inputfile, line);) 
{ 
    std::string f, a; 

    if (!(std::istringstream(line) >> f >> a)) { /* error */ } 

    (x.*functions[f])(a); 
} 
+0

這對我來說還是很難用的。 –

+0

@Saage:注意你可以使'func1'等泛型,作爲模板,比如'func_wrap <&Foo :: f1_impl>(std :: string)'等,因爲內容總是相同的。 –