2014-02-25 65 views
2

我試圖找出如何指針的容器寫信給不同對象的不同成員的功能(不同類的),像(僞)存儲指針的成員函數的容器

std::vector<std::function<??> > vec; 

template<class objectType, class parameter1> // This is just for 1-param funcs 
void add_to_vector(objectType& obj, void(objectType::*ptrToFunc)(parameter1)) { 
    std::function<void(parameter1)> fun = std::bind(ptrToFunc, obj, std::tr1::placeholders::_1); 
    vec.push_back(fun); 
} 

現在我可以考慮向所有想要存儲成員函數的對象添加一個基類,但是如何調用相應的成員函數呢?

+1

所以真正的問題不是關於成員函數指針 - 它是如何存儲std :: functions的向量,其中每個都應該接受不同類型(或數量?)的參數?你需要另一層類型擦除(std :: function已經提供了1層) – David

+0

備份並描述你真正的問題。上面我們看到了一個零碎的描述,你不明白怎麼去解決你遇到的一個真正的問題。描述真正的問題既可以使上述內容更容易理解,也可以指出一條完全不同的途徑來解決它。 – Yakk

回答

2

這取決於你希望如何調用這些函數。如果他們要使用相同的簽名來調用,解決方案非常簡單:只保留一個函數向量。

#include <iostream> 
#include <vector> 
#include <functional> 

using namespace std; 
using namespace placeholders; 

struct Foo { 
    void value(int x) { cout << x << endl; } 
}; 

struct Bar { 
    void sum(int y, int z) { cout << (y + z) << endl; } 
}; 

int main() { 

    Foo foo; 
    Bar bar; 

    vector<function<void(int)>> vec; 
    vec.push_back(std::bind(&Foo::value, &foo, _1)); 
    vec.push_back(std::bind(&Bar::sum, &bar, _1, 1)); 

    for (auto f : vec) f(1); 

    return 0; 
} 

如果這個想法是保持與參數任意數量(類型)功能的載體,可以使用std::vector<boost::any>>

#include <boost/any.hpp> 

int main() { 

    Foo foo; 
    Bar bar; 

    typedef function<void(int)> F1; 
    typedef function<void(int,int)> F2; 

    vector<boost::any> vec; 
    vec.push_back(F1(bind(&Foo::value, &foo, _1))); 
    vec.push_back(F2(bind(&Bar::sum, &bar, _1, _2))); 

    for (boost::any& any : vec) { 
     if (F1* f1 = boost::any_cast<F1>(&any)) (*f1)(1); 
     else if (F2* f2 = boost::any_cast<F2>(&any)) (*f2)(1, 1); 
    } 

    return 0; 
} 

如果你需要更進一步,我建議你閱讀更多關於type erasure