c++ - 访问作为参数传递的对象的不同成员的模板

标签 c++ templates class-members

我有一个函数来计算定义在一组相邻点上的不同变量的梯度。算法总是相同的,但是根据计算的内容,访问邻居的不同成员数据,例如计算速度梯度时,使用Node::velocity,计算应力梯度时,使用Node::stress >。避免多次编写相同函数的最佳方法是什么?

我想到了几种可能性:

  1. 传递 lambda 函数 (c++0x) 或返回有问题的特定成员数据的可调用对象,称为 like

    gradVelocity=computeGradient(listOfNeighbors,[](const Node& n){ return n.velocity; });
    

    缺点是每次读取都会调用额外的函数。

  2. 根据表示正在计算的整数的函数模板化:

    enum{VAL_VELOCITY=0,VAL_STRESS,VAL_SOMETHING};
    template<int what> computeGradient(const std::list<Node>& neighbors){
        /*loop over neighbors*/
             value=(what==VAL_VELOCITY?neighbor.velocity:((what==VAL_STRESS)?neighbor.stress:neighbor.something);
        /* and so on */
    }
    
    /* called like this */
    gradVelocity=computeGradient<VAL_VELOCITY>(neighbors);
    

    它应该是高效的(希望编译器能够优化带有常量的条件语句,但可读性和可维护性却很低。

有更好的主意吗?

最佳答案

如果您所有的字段都具有相同的类型,那么使用指向成员的指针就很容易:

struct Node
{
  double stress;
  double velosity;
};

void foo(Node* pNode, double Node::*pValue)
{
  cout << pNode->*pValue << endl;
}

int main()
{
  Node n1 = { 1, 2 };

  foo(&n1, &Node::stress);
  foo(&n1, &Node::velosity);
}

更新:如果没有,将指向成员的指针与模板结合起来仍然很容易:

struct Node
{
  double stress;
  double velosity;
  int dimension;
};

template<class T>
void foo(Node* pNode, T Node::*pValue)
{
  cout << pNode->*pValue << endl;
}

int main()
{
  Node n1 = { 1, 2 };

  foo(&n1, &Node::stress);
  foo(&n1, &Node::velosity);
  foo(&n1, &Node::dimension);
}

我认为这可能是最有效的方法。它也很生动。

关于c++ - 访问作为参数传递的对象的不同成员的模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7317019/

相关文章:

c++ - 在 C++ 中选择重载模板函数时的优先级

c++ - std::shared_ptr、继承和模板参数推导问题

c++ - 如何在没有 Boost 的情况下将 C++ 成员函数作为线程执行?

c++ - 类数据成员的初始化顺序

c++ - Visual Studio : E0349 no operator << matches these operands (but no strings in code)

c++ - ';' token 之前的预期类型说明符

c++ - 使用c++更改任何linux用户密码

c++ - 我如何修改此函数,以便如果函数的参数是特定结构,它会返回具有更大整数的结构?

c++ - 使用 default_random_engine 作为类成员并且没有类会导致不同的数字(相同的种子)

c++ - 正确使用 boost::mpl::contains 和 static_assert