简体   繁体   English

存储指向成员函数的指针的容器

[英]Storing a container of pointers to member functions

I'm trying to figure out how to write a container of pointers to different members functions for different objects (of different classes), something like (pseudocode) 我试图弄清楚如何为不同对象(不同类)的不同成员函数编写指针容器,例如(伪代码)

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);
}

for now I could just think of adding a base class to all the objects I want to store the member functions, but then how to call the appropriate member function anyway? 现在,我可以考虑为所有要存储成员函数的对象添加基类,但是无论如何如何调用适当的成员函数?

It depends on how you wish to call these functions. 这取决于您希望如何调用这些函数。 If they are going to be called using the same signature, the solution is quite straightforward: just keep a vector of functions. 如果要使用相同的签名来调用它们,则解决方案非常简单:只需保留函数向量即可。

#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;
}

If the idea is to keep a vector of functions with arbitrary number (and type) of parameters, you can use std::vector<boost::any>> . 如果要保留带有任意数量(和类型)参数的函数向量,则可以使用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;
}

If you need to go deeper, I would recommend you to read more about type erasure . 如果您需要进一步研究,我建议您阅读有关类型擦除的更多信息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM