gpt4 book ai didi

c++ - 是否可以使用参数包来允许模板函数接受等效类型?

转载 作者:搜寻专家 更新时间:2023-10-31 01:06:09 25 4
gpt4 key购买 nike

这个问题与几年前 Georg Fritzsche 在 SO 上关于转换参数包 (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;
}

最佳答案

这在语法方面回答了你的问题,如果我理解正确的话:是的,这是可能的。

// given int or char lvalue, returns its address
template<class T>
T* transform(T& t) {
return &t;
}

// given int* or char*, simply returns the value itself
template<class T>
T* transform(T* t) {
return t;
}

// prints out the address corresponding to each of its arguments
void f_std() {
}

template<class Arg, class... Args>
void f_std(Arg arg, Args... args) {
std::cout << (void*)arg << std::endl;
f_std(args...);
}

// converts int to int*, char to char*, then calls f_std
template<class... Args>
void f(Args... args) {
f_std(transform(args)...);
}

不幸的是,调用f 将按值传递intchar 参数,因此复制 它们。要解决此问题,请在 f 的定义中使用完美转发:

template<class... Args>
void f(Args&&... args) {
f_std(transform(std::forward<Args>(args))...);
}

司机:

int main() {
int x = 1;
char c = 'a';
cout << (void*)&x << endl;
cout << (void*)&c << endl;
f(x, &x, c, &c);
}

输出(示例;刚才在我的机器上运行它):

0x7fff36fb5ebc
0x7fff36fb5ebb
0x7fff36fb5ebc
0x7fff36fb5ebc
0x7fff36fb5ebb
0x7fff36fb5ebb

关于c++ - 是否可以使用参数包来允许模板函数接受等效类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21397817/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com