如何最好地将方法传递到同一类的方法 [英] How to best pass methods into methods of the same class

查看:108
本文介绍了如何最好地将方法传递到同一类的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个C ++类,一个大的复杂的方法 compute ,我想用'计算内核',同一个类的方法。我想我会按照

I have this C++ class that one big complicated method compute that I would like to feed with a "compute kernel", a method of the same class. I figure I would do something along the lines of

class test {
int classVar_ = 42;

int compute_add(int a, int b)
{
   compute(int a, int b, this->add_())
}

int compute_mult(int a, int b)
{
   compute(int a, int b, this->mult_())
}


int compute_(int a, int b, "pass in add or multiply as f()")
{
   int c=0;
   // Some complex loops {
   c += f(a,b)
   // }
   return c;
}

int add_(int a, int b){a+b+classVar_;}
int multiply_(int a, int b){a*b+classVar_;}
...

}

不知道我将如何传递添加乘法
这种方法的替代方法是传递某种类型的 ENUM 来指定 add() multiply(),但我想避免切换 if

but I'm not sure how I would pass in add or multiply. An alternative to this approach would be to pass in an ENUM of some sort to specify add() or multiply(), but I wanted to avoid a switch or if inside the loops.

推荐答案

如你所知,传递成员函数指针是可接受的做法。

As you suspected, passing a member function pointer is acceptable practice.

如果你需要知道语法,它是:

If you need to know the syntax, it is:

int compute_(int a, int b, int (test::*f)(int,int))
{
   int c=0;
   // Some complex loops {
   c += (this->*f)(a,b)
   // }
   return c;
}

使用整数和切换表示成员函数,引入程序员开销到当可用操作的列表改变时。因此,除非在特定情况下有一些重要的原因,否则不要这样做。

Representing member functions using integers, and switching, introduces programmer overhead to keep things up to date when the list of available operations changes. So you don't want that unless there's some important reason in a particular case.

一种替代方法是使 compute 更一般的 - 而不是采取成员函数,写一个函数模板,它接受任何可调用的类型:

One alternative is to make compute even more general -- instead of taking a member function, write a function template that takes any callable type:

template <typename BinaryFunction>
int compute_(int a, int b, BinaryFunction f) {
    // body as before but `f(a,b)` instead of `(this->*f)(a,b)`
}



这个更通用的模板是伟大的,如果有人想要使用它他们自己发明的操作符,这不是 test 的成员函数。但是在成员函数的情况下使用起来更困难,因为有人需要捕获 this 。有几种方法可以做到这一点 - 一个C ++ 11 lambda, boost :: bind ,或者写一个函子长。例如:

This more general template is great if someone wants to use it with some operator of their own invention, that isn't a member function of test. It's more difficult to use in the case of the member function, though, because someone needs to capture this. There are a few ways to do that -- a C++11 lambda, boost::bind, or writing out a functor longhand. For example:

template <typename BinaryFunction>
int compute_(int a, int b, BinaryFunction f) {
    // body as before with `f(a,b)`
}

int compute_(int a, int b, int (test::*f)(int,int))
{
    return compute_(a, b, bind_this(f, this));
}

定义 bind_this 有点疼痛:它像 std :: bind1st ,除了我们想使用3-arg函数,而 bind1st 只接受一个二元函子。在C ++ 11中的 boost :: bind std :: bind 更灵活,额外参数。下面将对这种情况做一下,但通常不能绑定2-arg成员函数:

Defining bind_this is a bit of a pain: it's like std::bind1st except that we'd like to work with a 3-arg functor whereas bind1st only takes a binary functor. boost::bind, and std::bind in C++11, are more flexible, and will handle the extra arguments. The following will do for this case, but doesn't work in general to bind 2-arg member functions:

struct bind_this {
    int (test::*f)(int,int);
    test *t;
    int operator(int a, int b) const {
        return (t->*f)(a,b);
    }
    bind_this(int (test::*f)(int,int), test *t) : f(f), t(t) {}
};

在C ++ 11中,您只需使用一个lambda:

In C++11 you can just use a lambda:

int compute_(int a, int b, int (test::*f)(int,int))
{
    return compute_(a, b, [=](int c, int d){ return (this->*f)(c,d) });
}

这篇关于如何最好地将方法传递到同一类的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆