首页 > 解决方案 > 将所有未知的方法调用和属性使用转发到 C++ 中的特殊函数

问题描述

在 C++ 中,如果我有某个类的对象,Class obj;我希望能够拦截和处理任何名称和参数的方法的调用,例如. obj.add(123),也可以处理任何属性使用,例如auto x = obj.value;.

问题是我不知道将使用什么方法或属性名称,例如可以使用obj.abc(1, 2, true)or auto x = obj.xyz;

因此,如果有人打电话给obj.abc(1, 2, true)我,我希望用 args 调用下一个方法("abc", 1, 2, true)

template <typename ... Args>
std::any ProcessMethod(std::string const & method_name, Args && ... args) {/*...*/}

或者如果使用了属性,auto x = obj.xyz;我希望使用("xyz")参数调用下一个方法:

std::any ProcessProperty(std::string const & property_name) {/*...*/}

上面这两种方法使用运行时方法。对我来说更好的是在编译时传递调用的方法或属性名称(作为编译时固定字符串)。这样我就可以在编译时找出方法返回类型或属性类型,即做(对于一些特殊的类 FixedString 在编译时保存字符串):

template <FixedString method_name, typename ... Args>
typename ReturnTypeOf<method_name>::type ProcessMethod(Args && ... args) {/*...*/}

template <FixedString property_name>
typename PropertyTypeOf<property_name>::type & ProcessProperty() {/*...*/}

无论如何,这是否有可能拦截对未知方法或属性的所有调用并将它们转发到上面的最后两个方法?

当然,我可以使用下一个语法:obj.call<"abc">(1, 2, true)auto x = obj.prop<"xyz">();解决我的任务,但是如果可以在 C++ 中解决任何问题,我想保留语法obj.abc(1, 2, true)auto x = obj.xyz;.

上面最后的语法是否可以通过 C++ 反射或模板魔术来实现?

标签: c++methodsreflectionpropertiesattributes

解决方案


这在 C++ 中是不可能的。您不能.以这种方式重载运算符 (**)。这更像是一种动态语言功能。

如果你真的想要,你可以编写一个编译器扩展来变成a.b(arg)已知不是.a.call("b", arg)ba

** 已经讨论过重载.,但设计不支持你想要的。见:http ://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4477.pdf


推荐阅读