我创建了一个小函数包装器示例。我想让包装器考虑被调用的函数是否使用(const)引用,这意味着输出将是4/5而不是4/4,但是如果包装函数没有,我不想强制引用使用它们。
#include <iostream>
#include <string>
struct a {
static void run(int cref) {
cref = 5;
};
};
struct b {
static void run(int &cref) {
cref = 5;
};
};
template <class FTor>
struct foo {
template <class ... Args>
static void wrapper(Args ... args) {
FTor::run(args ...);
}
};
int main()
{
int bar = 4;
foo<a>::wrapper(bar);
std::cout << bar;
foo<b>::wrapper(bar);
std::cout << bar;
}
那么使用完美转发怎么样?
template <class FTor>
struct foo {
template <class ... Args>
static void wrapper(Args && ... args) {
FTor::run(std::forward<Args>(args) ...);
}
};
这样,无论参数对输入的ref-qualification是什么,都会传递给内部函数。
这是一个尝试回答可能是我对OP请求的误解,因为简单的完美转发解决了所描述的场景,而没有求助于包装函数参数的类型推导。
原始答案:至少对于您正在呈现的受限用例,您可以使用小型特征结构来推断从仿函数的参数类型传递给wrapper()
的单个参数的类型:
#include <iostream>
#include <string>
struct a {
static void run(int cref) {
cref = 5;
};
};
struct b {
static void run(int &cref) {
cref = 5;
};
};
template <typename>
struct ArgType;
template <typename R, typename A>
struct ArgType<R(A)>
{ using type = A; };
template <class FTor>
struct foo {
static void wrapper(typename ArgType<decltype(FTor::run)>::type args) {
FTor::run(args);
}
};
int main()
{
int bar = 4;
foo<a>::wrapper(bar);
std::cout << bar;
foo<b>::wrapper(bar);
std::cout << bar;
}
输出:
45
请注意,这不支持包装器内的完美转发,因为wrapper()
本身不是*类型推理上下文的一部分 - 而不是你的片段,它推断但不是基于你想要推断的内容。我希望有时间为变量函数模板添加一个通用解决方案,例如在你的代码片段中,包括完美转发。