我可以指定或选择类的成员(并将其用作参数)吗?

时间:2017-03-30 19:34:39

标签: c++ reflection class-members

例如,假设我有:

class AB { float a,b; };

如何根据传入的参数以“正确”的方式编写一个可以处理ab的函数?我想做这样的事情:

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

2 个答案:

答案 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;
}