【问题标题】:How to call function member with different argument several times?如何多次调用具有不同参数的函数成员?
【发布时间】:2021-02-06 10:24:39
【问题描述】:

我的课程具有遵循简单模式的功能,但我不知道是否有避免代码重复的方法,所以它会更短。这是一个简化的例子:

class Data
{
public:
    void compute()
    {
        if (procedure1)
        {
            runAlpha(param1);
            runAlpha(param2);
            runAlpha(param3);
        }
        if (procedure2)
        {
            runBeta(param1);
            runBeta(param2);
            runBeta(param3);
        }
        if (procedure3)
        {
            runGamma(param1);
            runGamma(param2);
            runGamma(param3);
        }
    }
}

runAlpharunBetarunGamma 也是这个类的公共成员。如您所见,每个procedure 之间以及run 调用之间几乎没有区别。我想稍微简化一下这段代码,但是我不允许修改run函数,所以我考虑使用模板。但是,将 callMultipleRuns 方法添加到类并替换 if 语句的主体不会编译。

template <typename Run>
void callMultipleRuns(Run r)
{
    r(param1);
    r(param2);
    r(param3);
}

void compute()
{
    if (procedure1)
        callMultipleRun(runAlpha);
    if (procedure2)
        callMultipleRun(runBeta);
    if (procedure3)
        callMultipleRun(runGamma);
}

错误是error: invalid use of non-static member function。我无法将 static 添加到 run 声明中。有办法解决吗?

【问题讨论】:

  • param1、param2 等可以在 std::array 或 std::vector 中吗?如果是这样,这可以通过迭代它们来简化,或者使用其他在值范围内执行函数的构造。
  • 肯定有一个简单的“修复方法”,但您需要显示真实代码,minimal reproducible example,而不是虚构代码。对于带有假代码的问题,唯一可能的答案也是假答案。如果有人花时间根据编造的代码拼凑一个答案,却发现翻译中丢失了一些微小的细节,并且给出的答案由于某种原因不起作用,那将是一种耻辱。我打算写一个简单的解决方案,但意识到我可能会错过一些你没有提到的细节,这将使它没有实际意义。

标签: c++ function templates


【解决方案1】:

首先,您发现不能简单地将非静态成员函数作为参数传递。但是,您可以传递对成员函数的引用。这必须采用标准指定的特定形式。

一些示例代码

#include <cstdio>
class Data {
public:
    void runAlpha(int i) { printf("a%d", i); };
    void runBeta(int i) { printf("b%d", i); };
    void runGamma(int i) { printf("c%d", i); };

    template <typename Run>
    void callMultipleRuns(Run r)
    {
        (this->*r)(1);
        (this->*r)(2);
        (this->*r)(3);
    }

    void compute()
    {
        if (true) callMultipleRuns(&Data::runAlpha);
        if (true) callMultipleRuns(&Data::runBeta);
        if (true) callMultipleRuns(&Data::runGamma);
    }
};

int main() {
    Data{}.compute();
}

on Godbolt

【讨论】:

    【解决方案2】:

    你很亲密,但你不能像这样使用runAlpha 和朋友作为独立函数;他们需要一个实例。

    幸运的是,C++ 标准库为此提供了帮助。
    第一个是简单地传递一个 lambda 函数:

    callMultipleRuns([=](auto param) {runAlpha(param);})
    

    或使用std::bind:

    callMultipleRuns(std::bind(&Data::runAlpha, this, std::placeholders::_1);
    

    【讨论】:

      猜你喜欢
      • 2020-12-08
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 2017-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-09
      相关资源
      最近更新 更多