C++中通过字符串参数调用类成员方法的替代方案及编译问题
编辑补充:getPropertySingle是类层级中最基类obj2_t的类方法,与fAggregate所属的最基类obj_t不同。
此前我认为这无关紧要(为简化描述省略了该信息,现补充),而关于obj_t::*fAggregate的问题已解决,代码现已可编译。该方法如下:
template<typename retval_t> const retval_t obj2_t::getProperty( const obj_t& obj, const retval_t (*fProp)(const vec_t&, const string&, const int), const retval_t (obj_t::*fAggregate)(const retval_t&), const vec_t& vec, const string& s, const int i) { const retval_t retval = getPropertySingle<retval_t>(fProp, vec, s, i); return obj.*fAggregate(retval); };
但所有目标fProp均为obj2_t的非静态成员函数。每个特定的fProp对应一个特定的fAggregate,因此在指定fProp时(这正是模板化的原因)无需额外模板参数。示例如下:
const int obj2_t::getX( const obj_t& obj, const vec_t& vec, const string& s, const int i) { const int retval = getProperty<int>(obj, obj2_t::getXSingle, obj.AggregateX, vec, s, i); return retval; };
这会触发编译错误invalid use of non-static member function...,该问题需单独探讨。
我有一个模板函数obj2_t::getPropertySingle,它接收一个函数指针作为参数(后续会编写显式实例化代码)。模板化的核心目的是让返回类型不同的各类函数fProp都能作用于同一组参数(vec, s, i),后续可能需要将其改为可变参数模板。
template<typename retval_t> const retval_t obj2_t::getPropertySingle( const retval_t (*fProp)(const vec_t&, const string&, const int), const vec_t& vec, const string& s, const int i) { return fProp(vec, s, i); };
我还编写了另一个模板函数obj2_t::getProperty,其参数包括:
- 类层级中任意类的对象
obj(obj_t为最基类); - 所有类都应具备的方法
fAggregate; - 与
obj2_t::getPropertySingle相同的参数,以便调用该函数。
template<typename retval_t> const retval_t obj2_t::getProperty( const obj_t& obj, const retval_t (*fProp)(const vec_t&, const string&, const int), // 选项1: const string fAggregateStr, // 选项2: const retval_t (*fAggregate)(const retval_t&), const vec_t& vec, const string& s, const int i) { const retval_t retval = getPropertySingle<retval_t>(fProp, vec, s, i); return obj."fAggregateStr"(retval); // <---- 如何实现此功能? };
我原本希望以字符串形式传递fAggregate(即上述选项1),但C++不支持这种反射特性。
是否有其他可行的替代方案?
我不确定选项2(传递函数指针)是否适用,因为fAggregate方法需要结合obj对象和方法名来调用。我可以将obj从参数列表中移除,直接在调用处传递obj."fAggregateStr"作为fAggregate,但这样会失去将任意obj_t对象与任意fAggregate方法组合的灵活性。
此前找到的变通方案在我的场景中过于复杂,甚至可能不可行。
补充说明
- 我设想过
obj_t不一定属于单一类层级的场景,这种情况下可能还需要对该参数进行模板化。 - 在我的场景中,
fAggregate是最基类obj_t的成员方法,需求可自动满足;但在上述跨类层级场景中则无法自动满足。
内容的提问来源于stack exchange,提问作者sancho.s ReinstateMonicaCellio

