我有一个系统通过代码生成的代理对象Proxy<T>
提供远程过程调用:
struct Foo {
void bar(int);
void bar(double);
};
#include "generated_code_for_proxy_foo.h"
Proxy<Foo> p;
p.bar(7);
p.bar(6.5);
我想从代码生成转向直接使用C ++本地设施。这将节省我的用户必须学习和应用代码生成器,并将保存开发团队必须维护这个代码生成器,最终必须解析越来越多的C ++。
我希望能够按照
的方式实现模板方法remote_call(p, &Foo::bar, 7);
可以使用我想要调用的成员的代理对象和名称,并做正确的事。
如果我按如下方式定义remote_call
,只要Foo::bar
不是重载或模板,或者参数类型与重载集中其中一个成员完全匹配,就可以正常工作:
template <typename T, typename ...Args>
void remote_call(Proxy<T> p, void (T::*method)(Args...), Args ... args);
但是,如果我有像
这样的目标类型struct Baz {
void qux(int);
void qux(std::string);
};
然后打电话
remote_call(p, &Baz::qux, "string literal");
无法编译,因为&Baz::qux
并未解析为实际应用于
Baz b;
// Converts "string literal" to std::string, calls Baz::qux(std::string)
b.qux("string literal");
这就是我现在所拥有的,甚至将成员函数的复杂性简化为裸函数过载情况:
#include <type_traits>
using std::enable_if_t;
using std::is_convertible_v;
template <
typename Params,
typename Args,
typename Method = void (*)(Params),
typename = enable_if_t<is_convertible_v<Args, Params>>
>
void remote_call(Method method, Args args)
{
using R = decltype((*method)(args));
};
#include <string>
void bar(int);
void bar(std::string);
void test()
{
remote_call(&bar, "string literal");
}
如果某人有一种技术可以为单一论证案例做这项工作,那么我应该可以从那里进行推广。我想避免在我的调用者上承担重载解析,模板实例化,参数转换以及前面结果的显式指定。如果源代码中出现调用表达式f.bar("string literal")
,编译器将知道它将执行的操作。我想找到一些方法让它在没有立即生成代码来进行调用的情况下应用这些知识。