【发布时间】:2014-01-28 05:46:40
【问题描述】:
这个问题与几年前 Georg Fritzsche 关于转换参数包 (Is it possible to transform the types in a parameter pack?) 的一个问题有关。最后,可以转换参数包中的各个类型,例如通过转换为相应的指针类型。
我想知道是否可以使用这种技术编写一个标准函数/函子和一组包装器函数(在一个模板之外),以便包装器可以获取等效类型的参数,然后调用标准函数做实际的工作。
使用 Johannes Schaub 的答案 - 点燃下面的原始示例。是否可以编写一个模板f,它可以采用int/int*,char/char* 的任意组合并调用通用函数f_std(int*,char*) 来完成这项工作。 (参数个数没有预先指定。)
--- 更新 ---
例如,给定int i; char c;,是否可以使用包转换编写调用程序,以便以下工作
call_ptr(f_std,i,c);
call_ptr(f_std,&i,c);
call_ptr(f_std,i,&c);
下面列出了我到目前为止所尝试的内容(已更新以澄清。)。基本上,在调用采用指针类型的 std::function 之前,我尝试接受不一定是指针类型的列表并将它们转换为指针类型。但是代码无法编译。我不知道如何编写一个辅助函数来接受一个具有标准签名的函数,但接受一个其他的参数包。
提前致谢
#include <type_traits>
#include <functional>
using namespace std;
template<class... Args> struct X {};
template<class T> struct make_pointer { typedef T* type; };
template<class T> struct make_pointer<T*> { typedef T* type; };
template<template<typename...> class List,
template<typename> class Mod,
typename ...Args>
struct magic {
typedef List<typename Mod<Args>::type...> type;
};
/////////////////
// trying to convert parameter pack to pointers
template<class T> T* make_ptr(T x) { return &x; }
template<class T> T* make_ptr(T* x) { return x; }
template <typename Value, typename ...Args>
class ByPtrFunc
{
public:
typedef typename magic<X, make_pointer, Args...>::type PArgs;
Value operator()(Args... args) { return f(make_ptr(args)...); }
private:
std::function<Value (PArgs...)> _ptr_func;
}; //ByPtrFunc
//helper function to make call
template<typename A, typename ...Args>
static A call_ptr(std::function<A (Args...)> f, Args... args) {
return ByPtrFunc<A, Args...>{f}(args ...);
}
int main() {
typedef magic<X, make_pointer, int*, char>::type A;
typedef X<int*, char*> B;
static_assert(is_same<A, B>::value, ":(");
int i=0; char c='c';
function<int (int* pa,char* pb)> f_std = [](int* pa,char* pb)->int {return *pa + * pb;};
f_std(&i,&c);
//////////////////
//Is the following possible.
call_ptr(f_std,i,c);
call_ptr(f_std,&i,c);
call_ptr(f_std,i,&c);
return 0;
}
【问题讨论】:
-
f 可以接受多少个参数?它是可变参数还是只有 2 个?您可以使用std::is_pointer 检查参数是否为指针,如果不是则添加指针。
-
@Gasim variadic,很有趣。
-
我认为您要问的是不可能的,因为转换类型会阻止模板参数推导,从而阻止重载解析。但也许比我聪明的人会想出一个解决方法。