C++ - 两个成员函数因单个函数调用而异

标签 c++ templates function-pointers

我正在尝试改进我的 C++ 编码,我想问一下以下问题的最有效和最优雅的解决方案是什么:

我实现了一个具有两个成员函数的类。他们都填补了 double 的数组。这些函数的主体是相同的,除了内部有一个调用之外。在其中一个中,我想调用幂函数pow(x[idx], Moment)。另一方面,我想调用不同类的另一个对象的另一个成员函数。

#include <vector>
#include <cmath>

class Pot {
  public:
    Pot() {}
    virtual double GetPot(const double x) const {return sin(x);}
    virtual ~Pot() {}
}

class BSplOper {
  private:
    const Pot *m_p;
    ... (other private members)
  public:
    BSplOper(const Pot *p) : m_p{p} {}
    virtual ~BSplOper() {}
    void MkMat1();
    void MkMat2();
}

void BSplOper::MkMat1() {
  double val = 0.0;
  for (some nested loops here) {
    ... (some more code - index transformations, etc)
    for (int indx = 0; indx < LargeNumber; indx++) {
      ... (some more nested loops)
      val += pow(x[indx], someconst);
    }
  }
}

void BSplOper::MkMat2() {
  double val = 0.0;
  for (the same code as in MkMat1) {
    ...(the same code as in MkMat1)
    for (int indx = 0; indx < LargeNumber; indx++) {
      ... (the same code as MkMat1)
      val += m_p->GetPot(x[indx]);
    }
  }
}

有没有办法将其实现为单个函数,该函数有一个参数决定内部将调用哪个函数?问题是这个函数会被调用很多次,它的性能非常重要。它位于一系列嵌套循环内。因此,我不想在里面添加条件。

我正在考虑使用 std::function 作为此成员函数的参数,它将传递对预期函数的引用。但是,我不确定 std::function 的开销。

使用模板化成员函数会更有效吗?类似的东西

template<typename F>
void BSplOper::MkMat(F fnx) {
  double val = 0.0;
  for (the same code as in MkMat1) {
    ...(the same code as in MkMat1)
    for (int indx = 0; indx < LargeNumber; indx++) {
      ... (the same code as MkMat1)
      val += (*fnx)(x[indx]);
    }
  }
}

在这种情况下,调用它的正确语法是什么?或者这两种解决方案都是完全错误的?谢谢您的推荐。

最佳答案

使用函数指针的缺点是编译器可能无法执行所有可能的优化,因此您希望在编译时为编译器提供尽可能多的信息。

为此,您可以将该信息作为模板参数而不是函数参数传递。

一种方法是结合使用 if constexpr 和模板参数。

下面的代码只是一个快速而简单的示例,说明了如何做到这一点。但您可能想使用 bool 之外的其他内容。

struct BSplOper {

    template<bool F>
    void MkMat() {
      double val = 0.0;
      for (some nested loops here) {
        ... (some more code - index transformations, etc)
        for (int indx = 0; indx < LargeNumber; indx++) {
          ... (some more nested loops)
          
          if constexpr(F) {
            val += pow(x[indx], someconst);
          } else {
            val += m_p->GetPot(x[indx]);
          }
        }
      }
    }

    void MkMat1() {
        MkMat<true>();
    }

    void MkMat2() {
        MkMat<false>();
    }
};

就可维护性和语义而言,if constexpr 并不是最佳解决方案。但如何以正确的方式解决这个问题取决于实际的代码和值依赖关系以及运行时间。

关于C++ - 两个成员函数因单个函数调用而异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66869050/

相关文章:

C++::Template 函数 - 从 object.function 获取对象的地址

c++ - 当参数是函数参数包时,在部分排序期间推导模板参数

c++ - 在仿函数的 c'tor 中搜索值

C++音乐专辑打印轨道标题

c++ - 用作模板的类中的静态常量变量

C++ - 具有任意数量参数的函数指针

function-pointers - Ada 访问无参数过程 "wrong convention"

c++ - 错误 : 'a pointer to member is not valid for a managed class'

c++ - 指数的前 n 位

c++ - 指针保留字符串