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);
精彩评论