我有一个函数来计算定义在一组相邻点上的不同变量的梯度。算法总是相同的,但是根据计算的内容,访问邻居的不同成员数据,例如计算速度梯度时,使用Node::velocity
,计算应力梯度时,使用Node::stress
>。避免多次编写相同函数的最佳方法是什么?
我想到了几种可能性:
传递 lambda 函数 (c++0x) 或返回有问题的特定成员数据的可调用对象,称为 like
gradVelocity=computeGradient(listOfNeighbors,[](const Node& n){ return n.velocity; });
缺点是每次读取都会调用额外的函数。
根据表示正在计算的整数的函数模板化:
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/