在 C++ 中将字符串/字符转换为类成员/方法
convert string/character to class member/method in c++
有没有办法将字符串或字符转换为类成员/成员函数以动态访问它们?
例如,这个特定的代码,
#include <iostream>
#include <map>
using namespace std;
class agnt {
public:
int x, y;
agnt(int a=0, int b=0) : x(a), y(b) {}
};
int main() {
map<int,agnt> agntID;
agnt temp;
temp.x=1;
temp.y=5;
agntID[1]=temp;
for(char tmp='x'; tmp<'z'; tmp++) {
cout<<agntID[1].tmp<<'n'; //Here I get the following error: tmp is
} //not a member of class agnt
}
有没有办法转换字符"tmp",使其被标识为类成员?任何提示或解决方案将不胜感激。
内省,所以不,这是不可能的。
但是,您可以通过使用另一个包含名称作为键的std::map
来"破解"它,并且该值是对变量的引用:
agnt temp;
std::unordered_map<char, int&> variable_map = {
{ 'x', temp.x },
{ 'y', temp.y }
};
variable_map['x'] = 123;
std::cout << variable_map['y'] << 'n';
不过,这通常不值得,因为它需要更多的工作。特别是如果你想对多个变量执行此操作(因为每个结构变量都需要自己的映射)。
你不能在C++中执行此操作,因为它是一种静态类型的语言。获得这种行为的一种方法是提供访问包装器:
template <char c>
struct getter {
};
template <>
struct getter<'x'> {
static int get(const agnt &theAgnt) {
return theAgnt.x;
}
};
template <>
struct getter<'y'> {
static int get(const agnt &theAgnt) {
return theAgnt.y;
}
};
template <char c>
int get(const agnt &theAgnt) {
return getter<c>::get(theAgnt);
}
并像这样打电话:
agnt temp;
//... set members
std::cout << get<'x'>(temp) << std::endl;
但是,for
循环不会按预期方式工作,因为需要在编译时确定模板参数。此外,您不能只请求任何旧的东西,除非您在返回某种 NULL 指示符的非专用getter
中定义了一个 get
函数,例如 INT_MIN
。
然而,这实际上是一个黑客,以获得与动态语言模糊相似的东西。但这与仅引用temp.x
没有什么不同。相反,您应该尝试遵守C++约定并享受静态类型!
否
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;
}
虽然每个回答"否"的人都是正确的......这并不能说明全部情况。语言中没有任何内容允许您这样做,但这并不意味着环境不允许这样做。
例如,在 vxworks 上,您可以调用 symFindByName()
来查找函数、变量或任何其他符号,然后可以通过它提供的指针调用该函数。但这依赖于OS API,并且可能是vxworks链接器工作方式的副作用。
其他操作系统可能具有类似的功能。
- 从私有成员变量的成员方法返回unique_ptr
- 如何将类成员方法的参数列表自动填充写入可变参数?
- 如何对绑定的成员方法进行typedef,然后将该类型用作模板参数
- 从类C++外部调用指向成员方法的成员指针
- 在另一个 QThread 上运行成员方法时,无法将事件发送到其他线程拥有的对象
- 对成员类型的成员方法使用 std::result_of<>
- 我是否应该在构造函数或成员方法中进行大量初始化工作
- 如何检查是否调用了成员方法
- 我怎么可能从尚未定义某些成员方法的类创建实例?(C++)
- 有没有办法强制对 clang-format/clang-tidy 中的类成员/方法使用 "this->"?
- 指向 objc 类成员方法的函数指针,用于C++
- 对集合调用成员方法
- JetBrains CLion 不能建议字符串的成员方法
- 我无法在班级中获得MED股票来调用成员方法
- 如何在本机回调中使用Cython CDEF类成员方法
- 通过指针从for_each循环中访问成员方法
- 调用成员方法时会丢失此指针
- 为什么点运算符(.)可以与私有类成员/方法一起使用
- 静态调度以使用聚合类型的层次结构更正成员方法
- 显式模板专用化不能具有存储类 - 成员方法专用化