我试图将以下两个函数组合成一个便携函数:
void NeedleUSsim::FindIdxRho()
{
searchTmp = &ninfo->rho;
double *p = std::find_if(tplRho_deg, tplRho_deg+sampleDim[2], &NeedleUSsim::GreaterThanOrEqualTo);
while(p != tplRho_deg+sampleDim[2])
{
idxRho = p - tplRho_deg;
p = std::find_if(p+1, tplRho_deg+sampleDim[2], &NeedleUSsim::GreaterThanOrEqualTo);
}
}
void NeedleUSsim::FindIdxDepth()
{
searchTmp = &ninfo->l;
double *p = std::find_if(tplL, tplL+sampleDim[1], &NeedleUSsim::LessThanOrEqualTo);
while(p != tplL+sampleDim[1])
{
idxL = p - tplL;
p = std::find_if(p+1, tplL+sampleDim[1], &NeedleUSsim::LessThanOrEqualTo);
}
}
理想情况下,我希望函数的参数将tpl成员作为指针传递,并将大小和rho / l作为值传递。 searchTmp是一个文件范围双精度指针。有没有简单的方法将& NeedleUSsim :: GreaterThanOrEqualTo函数作为我正在尝试编写的函数的参数传递?
提前感谢您的建议。
答案 0 :(得分:6)
使代码更通用的最简单方法如下:
template<typename ComparisonType>
double* NeedleUSsim::FindIdx(double* containerBegin, double* containerEnd, ComparisonType comparison) {
double* p = std::find_if(containerBegin, containerEnd, comparison);
double* idx = 0;
while(p != containerEnd)
{
idx = p - containerBegin;
p = std::find_if(p+1, containerEnd, comparison);
}
return idx;
}
void NeedleUSsim::FindIdxRho()
{
searchTmp = &ninfo->rho;
double* idx = FindIdx(tplRho_deg, tplRho_deg+sampleDim[2], &NeedleUSsim::GreaterThanOrEqualTo);
if( idx != 0 )
{
idxL = idx;
}
}
void NeedleUSsim::FindIdxDepth()
{
searchTmp = &ninfo->l;
double* idx = FindIdx(tplL, tplL+sampleDim[1], &NeedleUSsim::LessThanOrEqualTo);
if( idx != 0 )
{
idxRho = idx;
}
}
答案 1 :(得分:3)
有没有简单的方法将&amp; NeedleUSsim :: GreaterThanOrEqualTo函数作为我正在尝试编写的函数的参数传递?
有几种方法可以做到这一点。
eJames上面介绍了第一种方法。
第二种方法涉及将比较函数包装在某个函数 - 对象层次结构中。函数对象是类()运算符重载的实例。这使得实例可以调用:
class IComparator
{
public:
virtual bool operator()(lhs, rhs) = 0;
}
class CComparatorLessThan : public IComparator
{
public:
virtual bool operator()(lhs, rhs) {...}
}
class CComparatorGreaterThan : public IComparator
{
public:
virtual bool operator()(lhs, rhs) {...}
}
您的常用函数将采用ICompatator引用,并且行为将在运行时动态绑定。
第三种方法涉及模板化而不是创建对象层次结构
template <class Comparator>
void foo(...)
{
...
Comparator comparer;
std::find_if(..., comparer);
}
然后调用foo将涉及:
foo<CComparatorGreaterThan>(...);
这消除了第二个解决方案的大量运行时开销。在这里,您不必定义基类。你只需要有某种类运算符()重载并返回bool。
答案 2 :(得分:1)
可以将成员函数指针传递给函数,如下所示:
typedef bool (NeedleUSsim::*compFunctionPtr)(NeedleUSsim &x, NeedleUSsim &y);
void NeedleUSsim::FindIdxRho(compFunctionPtr comparison)
{
//..
p = std::find_if(tplRho_deg, tplRho_deg+sampleDim[2], comparison);
//..
}
然后可以这样调用:
//..
someNeedleUSsim.FindIdxRho(&NeedleUSsim::LessThanOrEqualTo);
//..
有关详细信息,请查看this C ++ FAQ Lite文章。
答案 3 :(得分:1)
将函数和更复杂的参数放入函数的简单方法是对它们进行模板化(我猜测某些参数类型)
template <typename F>
void NeedleUSsim::FindIdx(double *ninfoMember, double *tplParam, size_t dimension, F CompareFunc, int &target)
{
searchTmp = ninfoMember;
double *p = std::find_if(tplParam, tplParam+sampleDim[dimension], CompareFunc);
while(p != tplParam+sampleDim[dimension])
{
target= p - tplParam;
p = std::find_if(p+1, tplParam+sampleDim[dimension], CompareFunc);
}
}
然后叫它:
FindIdx(&ninfo->rho, tplRho_deg, 2, &NeedleUSsim::GreaterThanOrEqualTo, idxRho);
FindIdx(&ninfo->l, tplL, 1, &NeedleUSsim::LessThanOrEqualTo, idxL);
答案 4 :(得分:1)
double *p = std::find_if(b, e, &NeedleUSsim::GreaterThanOrEqualTo);
while(p != e)
{
idxRho = p - b;
p = std::find_if(p + 1, e, &NeedleUSsim::GreaterThanOrEqualTo);
}
请注意,您使用的此循环不是必需的。使用反向迭代器
std::reverse_iterator<double*> rb(e), re(b);
rb = std::find_if(rb, re, &NeedleUSsim::GreaterThanOrEqualTo);
if(rb != re) {
idxRho = re - rb;
}
现在它的作用更加明显。如果只在发现某些内容时写入idxRho是错误或无关紧要,可以将其缩短为此
std::reverse_iterator<double*> rb(e), re(b);
idxRho = re - std::find_if(rb, re, &NeedleUSsim::GreaterThanOrEqualTo);