简体   繁体   English

指向成员函数的指针向量与多个对象c ++

[英]Vector of pointers to member functions with multiple objects c++

Considering this following code : 考虑以下代码:

class A
{
public:
    void aFoo() {}
};

class B
{
public:
    void bFoo() {}
};

class C
{
public:
    void c1Foo() {}
    void c2Foo() {}
};

Regardless the code architecture, is it possible to create a vector of pointers to member functions even if those functions are in multiple classes ? 无论代码架构如何,是否可以创建指向成员函数的指针向量,即使这些函数属于多个类?

In this case, inheritance is not a solution because we don't know how many functions we want to use in a class (class C has two functions). 在这种情况下,继承不是解决方案,因为我们不知道我们想在一个类中使用多少函数(C类有两个函数)。 But we know they all have the same prototype. 但我们知道它们都有相同的原型。

Member functions of different classes have different types. 不同类的成员函数有不同的类型。 So in order to have any homogeneous container (like std::vector or std::array ) of those you'll need to wrap them in some value type that may represent them all (like boost::variant or boost::any ). 因此,为了拥有任何同类容器(如std::vectorstd::array ),你需要将它们包装在一些可能代表它们的值类型中(如boost::variantboost::any ) 。

On the other hand if all you need are member functions of a specific type (for example void() ) and you don't mind passing the object on which they should be called before hand, then you can just store them as std::function<void()> (for this specific example) and just call std::bind on them before storing them in the container. 另一方面,如果您需要的只是特定类型的成员函数(例如void() ),并且您不介意传递应该在其之前调用它们的对象,那么您可以将它们存储为std::function<void()> (对于这个特定的例子),在将它们存储在容器中之前,只需在它们上调用std::bind

As an example, given: 举个例子,给出:

A a; B b; C c;
std::vector<std::function<void()>> vector {
    std::bind(&A::aFoo, a),
    std::bind(&B::bFoo, b),
    std::bind(&C::c1Foo, c),
    std::bind(&C::c2Foo, c)
};

you would be able to call: 你可以打电话:

for (auto fn : vector)
    fn();

Live demo 现场演示

I am not sure what you want to achieve so this may not be very helpful but here it is anyway. 我不确定你想要实现什么,所以这可能不是很有帮助,但无论如何它在这里。

As others have said you cannot create a std::vector for this as the prototypes are different. 正如其他人所说,你不能为此创建一个std :: vector,因为原型是不同的。 You can however create a std::tuple like this: 但是你可以像这样创建一个std :: tuple:

std::tuple<void (A::*)(), void (B::*)(), void (C::*)()> x(&A::aFoo, &B::bFoo, &C::c1Foo);

Assuming you have a an instance of a class, say A a then you can call the function as in (a.*std::get<0>(x))() . 假设你有一个类的实例,比如A a那么你可以调用该函数(a.*std::get<0>(x))()

If you have stored your objects in a tuple as well, then you can iterate over them. 如果您已将对象存储在元组中,则可以迭代它们。 The following code will do just that (assumes you have C++14 and Boost in your system) 以下代码将执行此操作(假设您的系统中有C ++ 14和Boost)

#include <iostream>
#include <tuple>
#include <type_traits>
#include <boost/mpl/find_if.hpp>
#include <boost/mpl/deref.hpp>
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <functional>

class A
{
public:
    void aFoo()
    {
        std::cout << "A" << std::endl;
    }
};

class B
{
public:
    void bFoo()
    {
        std::cout << "B" << std::endl;
    }
};

class C
{
public:
    void c1Foo()
    {
        std::cout << "C1" << std::endl;
    }

    void c2Foo() {}
};

// functor used by boost to iterate over the tuple

template <class Tuple>
struct functor
{
    functor(Tuple t)
    : m_tuple(t)
    {
    }

    template <class X>
    void operator()(X& x) const
    {
        using namespace boost::mpl;
        using iter = typename find_if<Tuple, std::is_same < placeholders::_1, void (X::*)()> >::type;
        using type = typename deref<iter>::type;
        return (x.*std::get<type>(m_tuple))();
    }

private:
    Tuple m_tuple;
};

template <class Tuple>
functor<Tuple> make_functor(Tuple t)
{
    return functor<Tuple>(t);
}

int main()
{
    std::tuple<void (A::*)(), void (B::*)(), void (C::*)() > x(&A::aFoo, &B::bFoo, &C::c1Foo);
    std::tuple<A, B, C> y;
    boost::fusion::for_each(y, make_functor(x));
}

Live demo here: http://coliru.stacked-crooked.com/a/e840a75f5b42766b 现场演示: http//coliru.stacked-crooked.com/a/e840a75f5b42766b

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

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