Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 转发成员函数参数_C++_Templates_Variadic Templates_Perfect Forwarding - Fatal编程技术网

C++ 转发成员函数参数

C++ 转发成员函数参数,c++,templates,variadic-templates,perfect-forwarding,C++,Templates,Variadic Templates,Perfect Forwarding,事情很简单,我想转发成员函数的调用及其参数,如下面的代码段所述 请注意,这不是的副本,也不是 #包括 #包括 模板 自动转发参数(函数和函数、参数和…参数) { 返回f(标准::转发(参数)…); } intf(inti){return i;} 结构A{ int get(int i)const{return i;} }; int main() { std::cout通过指向成员的指针调用成员函数仍然需要这个指针,就像通常的(直接)调用一样。简单地说,您可以成功调用a::get() static

事情很简单,我想转发成员函数的调用及其参数,如下面的代码段所述

请注意,这不是的副本,也不是

#包括
#包括
模板
自动转发参数(函数和函数、参数和…参数)
{
返回f(标准::转发(参数)…);
}
intf(inti){return i;}
结构A{
int get(int i)const{return i;}
};
int main()
{

std::cout通过指向成员的指针调用成员函数仍然需要
这个
指针,就像通常的(直接)调用一样。简单地说,您可以成功调用
a::get()

static auto wrong_wrapper = &A::get;
(a.*wrong_wrapper)(2);
但是在
forward\u args
被实例化之后得到的是

A::get(a, 2);
这在本质上是不正确的语法

解决方案

正如评论部分已经说过的,如果允许使用C++17,请使用。如果不允许,可以使用,它接受任何可调用类型

template<class Function, class ... Args>
auto forward_args(Function f, Args&& ... args)
{
    return std::ref(f)(std::forward<Args>(args)...);
}

通过指向成员的指针调用成员函数仍然需要
这个
指针,就像通常的(直接)调用一样。简单地说,您可以成功地调用
a::get()
like

static auto wrong_wrapper = &A::get;
(a.*wrong_wrapper)(2);
但是在
forward\u args
被实例化之后得到的是

A::get(a, 2);
这在本质上是不正确的语法

解决方案

正如评论部分已经说过的,如果允许使用C++17,请使用。如果不允许,可以使用,它接受任何可调用类型

template<class Function, class ... Args>
auto forward_args(Function f, Args&& ... args)
{
    return std::ref(f)(std::forward<Args>(args)...);
}

std::function
之所以有效,是因为它使用哪个函数来处理对成员函数的指针的调用

作为解决方案,您可以编写:

template<class Function, class ... Args>
auto forward_args(Function&& f, Args&& ... args) {
    return std::invoke(std::forward<Function>(f), std::forward<Args>(args)...);
}
或者,如果您有指向成员函数的指针:

using Ptr = int (A::*)(int) const;
Ptr p = &A::get;
A a;
(a.*p)(1);     // [1]
(obj.*memberFuncPtr)(args...);

第[1]行是调用指针指向的成员函数的有效语法。在本例中,您尝试使用无效且无法工作的
a::get(a,2)

std::function
工作,因为它使用处理对成员函数的指针调用的函数

作为解决方案,您可以编写:

template<class Function, class ... Args>
auto forward_args(Function&& f, Args&& ... args) {
    return std::invoke(std::forward<Function>(f), std::forward<Args>(args)...);
}
或者,如果您有指向成员函数的指针:

using Ptr = int (A::*)(int) const;
Ptr p = &A::get;
A a;
(a.*p)(1);     // [1]
(obj.*memberFuncPtr)(args...);

行[1]是调用指针指向的成员函数的有效语法。在您的例子中,您尝试了
a::get(a,2)
,这是无效的,无法工作。

好的,首先,我仍然不明白为什么
转发参数(&a::get,a,2)
不起作用。部分答案是“您需要
这个
”,但我实际上为它提供了第二个参数,对吗?这与
std::function
包装器有何不同

另一方面,虽然上面的答案中提出的解决方法对代码段起作用,但实际上我过于简化了我的原始问题

  • 线程安全已被删除
  • 是的,我想将所有调用打包在一个数据结构中,即
    任务
    ,这就是我开始构建包装器的原因
  • 我不明白如何将建议的解决方案用于下面的代码
#包括
#包括
#包括
#包括
std::队列任务;
模板
自动排队(函数&&f,参数&&…参数)->std::future
{
std::function func=std::bind(std::forward(f),std::forward(args)…);
自动任务_ptr=std::使_共享(func);
std::function wrapper=[task_ptr]()//用于匹配“tasks”类型的包装器
{
(*任务(ptr));
};
任务。推送(包装器);
返回任务->获取未来();
}
void indep(){}
结构A{
int get(int i)const{return i;}
};
int main()
{
排队(indep);
A A;
//排队(&A::get,A,2);//错误
静态自动包装错误=&A::get;
//排队(你错了,a,2);//又错了
静态std::函数包装器=&A::get;
排队(包装器,a,2);//好
静态自动转换tr=std::mem_fn(&A::get);
排队(autoptr,a,2);//再次确定

}
好的,首先,我仍然不明白为什么
转发参数(&A::get,A,2)
不起作用。部分答案是“您需要
这个
”,但我实际上为它提供了第二个参数,对吗?这与
std::function
包装器有什么不同

另一方面,虽然上面的答案中提出的解决方法对代码段起作用,但实际上我过于简化了我的原始问题

  • 线程安全已被删除
  • 是的,我想将所有调用打包在一个数据结构中,即
    任务
    ,这就是我开始构建包装器的原因
  • 我不明白如何将建议的解决方案用于下面的代码
#包括
#包括
#包括
#包括
std::队列任务;
模板
自动排队(函数&&f,参数&&…参数)->std::future
{
std::function func=std::bind(std::forward(f),std::forward(args)…);
自动任务_ptr=std::使_共享(func);
std::function wrapper=[task_ptr]()//用于匹配“tasks”类型的包装器
{
(*任务(ptr));
};
任务。推送(包装器);
返回任务->获取未来();
}
void indep(){}
结构A{
int get(int i)const{return i;}
};
int main()
{
排队(indep);
A A;
//排队(&A::get,A,2);//错误
静态自动包装错误=&A::get;
//排队(你错了,a,2);//又错了
静态std::函数包装器=&A::get;
排队(包装器,a,2);//好
静态自动转换tr=std::mem_fn(&A::get);
排队(autoptr,a,2);//再次确定

}
使用
返回std::invoke(std::forward(f),std::forward(args)…);
是否尝试将函数指针用作函数模板参数?使用
返回std::invoke(std::forward(f),std::forward(args)…)
您是否尝试使用指向函数的指针作为函数模板参数?如果您不关心SFINAE,您可以