例如,假设我有:
class AB { float a,b; };
如何根据传入的参数以“正确”的方式编写一个可以处理a
或b
的函数?我想做这样的事情:
float getSqrt(AB x, ClassMemberSelector s)
{ return sqrt(x.s); }
AB x;
getSqrt(x, SelectClassMember(AB::a) ); //get square root of x.a
getSqrt(x, SelectClassMember(AB::b) ); //get square root of x.b
答案 0 :(得分:4)
当然,这里有三个例子:
<强> 1)强>
float getSqrt(const AB& ab, function<float(const AB&)> selector)
{
return sqrt(selector(ab));
}
简化为(感谢NathanOliver&#39; s comment):
template<typename SelectorT>
float getSqrt(AB ab, SelectorT selector)
{
return sqrt(selector(ab));
}
(这个版本更好,因为它避免将lambda复制到std::function
)
和用法(两个版本都相同):
cout << getSqrt(x, [](const AB& ab) { return ab.a; }) << endl;
cout << getSqrt(x, [](const AB& ab) { return ab.b; }) << endl;
<强> 2)强>
另一种可能性是使用指向成员的指针:
float getSqrt(const AB& ab, float AB::*selector)
{
return sqrt(ab.*selector);
}
和用法:
cout << getSqrt(x, &AB::a) << endl;
cout << getSqrt(x, &AB::b) << endl;
第3)强>
使用类似TMP trait的过载选择的例子:
struct SelectAMemberT {};
struct SelectBMemberT {};
template<typename SelectorT>
float getSqrt(const AB& ab, SelectorT);
template<>
float getSqrt(const AB& ab, SelectAMemberT)
{
return sqrt(ab.a);
}
template<>
float getSqrt(const AB& ab, SelectBMemberT)
{
return sqrt(ab.b);
}
const SelectAMemberT SelectAMember;
const SelectBMemberT SelectBMember;
和用法:
cout << getSqrt(x, SelectAMember) << endl;
cout << getSqrt(x, SelectBMember) << endl;
答案 1 :(得分:0)
#include <iostream>
#include <cmath>
class AB
{
public:
float a, b;
};
float getSqrt(AB x, float AB::*mem)
{
return sqrt(x.*mem);
}
int main()
{
AB x;
x.a = 9;
x.b = 16;
std::cout << "sqrt x.a: " << getSqrt(x, &AB::a) << std::endl;
std::cout << "sqrt x.b: " << getSqrt(x, &AB::b) << std::endl;
system("pause");
return 0;
}