否
C++沒有內省和反射能力。您必須自己編寫這種動態訪問。
在某些情況下,使用外部模式文件來描述您的C++類,然後自動生成這些類以及內省和反射代碼,可以替代手動編碼。你不能使用模板來完成這個工作,因爲C++的元編程能力在這個領域完全不存在。
由於C++語法的複雜程度,通過直接解析.h
來生成代碼通常會困難得多(即使對於編譯器製造商來說,也需要花費相當多的時間才能就適當的C++代碼以及什麼不是)。
您可以使用模板來簡化發佈,但仍然做手工:
template<typename T, typename C>
std::map<std::string, T C::*>& attribute_map() {
static std::map<std::string, T C::*> m;
return m;
}
template<typename C>
struct Published {
template<typename T>
T& attribute(const std::string& name) {
std::map<std::string, T C::*>& m = attribute_map<T, C>();
typename std::map<std::string, T C::*>::const_iterator i=m.find(name);
if (i == m.end()) {
throw std::runtime_error("Attribute not present");
} else {
return static_cast<C *>(this)->*i->second;
}
}
};
對於每個屬性,你需要明確的「發佈」它
template<typename T, typename C>
void publish(const std::string& name, T C::*mp) {
attribute_map<T, C>()[name] = mp;
}
鑑於上述樣板代碼然後您可以創建一個課程並通過從Published<Class>
派生出版一些成員:
struct MyClass : Published<MyClass> {
int a;
double b;
std::string c;
MyClass(int a, double b, const std::string& c)
: a(a), b(b), c(c)
{
}
};
然後,你將需要在程序開始只是一次調用publish
功能,能夠動態地訪問屬性:
int main(int argc, const char *argv[]) {
publish("a", &MyClass::a);
publish("b", &MyClass::b);
publish("c", &MyClass::c);
MyClass m1(3, 4.5, "This is a test");
MyClass m2(6, 7.8, "This is another test");
std::cout << m1.attribute<int>("a") << "\n";
std::cout << m2.attribute<std::string>("c") << "\n";
return 0;
}