开发者

Is it possible to access member name from parameter

开发者 https://www.devze.com 2023-02-23 01:26 出处:网络
Please consider this class: class A { public://public in this example string a1; string a2; string a3; string a4;

Please consider this class:

class A
{
public:       //public in this example
  string a1;
  string a2;
  string a3;
  string a4;
  int a5;
  double a6;
  (...) plus other 50 member nam开发者_高级运维es

  multiset<string> getAttrib(const vector(A)& va, string attr)
  {
    for (vector<string>::const_iterator ci = va.begin; ci != va.end(); ++ci) {
      cout << ci->attr << endl;     //ERROR
  }
};

The member function could be called like:

A a
a.getAttrib(vector_a, "a1");

This results in an error. Const class A has no member named 'attr'.

I didn't want to write 50 different case statements to achieve the above wanted flexibility. Is it possible somehow? And if member names are private can a public member function exist to perform this?

Besides class A, I have six other similar classes and wanted to have a parent class that would take a vector of any of the seven classes and could return the value (or in the real case a multiset) of the chosen membername.


There's not a direct way to do what you want in C++, although there are some reasonable attempts at reflection frameworks out there. You might also look here: How can I add reflection to a C++ application? for additional commentary about reflection. I would suggest, however, that instead of having 50 member variables, you simply use one private std::hashmap and use std::string keys. You can then easily pass string parameters along as keys for direct lookups.

This, of course, assumes all your 50 members are of the same type, and that may not be suitable for your application. However, take my point, which is: do it a little differently.


You could use the X macro technique to map variables to indices of a container (e.g. a std::deque) that would contain your a_n. You should probably add an extra entry at the end which you could use to get the needed container size.


It sounds like you might want a pointer-to-member, although it might be better to change to a more flexible object representation, such as an array of discriminated unions (boost::variant) or C++11 std::tuple.

Anyway, with pointer-to-member, you could have

  template< typename Attr_Type >
  static vector< Attr_Type > getAttrib(const vector<A>& va, Attr_Type A:: *attr)
  {
    vector< Attr_Type > ret;
    for (vector<A>::const_iterator ci = va.begin(); ci != va.end(); ++ci) {
      cout << ci->*attr << endl;
      ret.push_back( ci->*attr );
    }
    return ret;
  }

use as

vector< A > vector_a;
vector< string > vector_a_a1 = A::getAttrib(vector_a, &A::a1);
0

精彩评论

暂无评论...
验证码 换一张
取 消