Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.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++ 通过std::function<;安全吗;bool(标准::字符串)>&&;回调(即作为右值移动)及其效果如何?_C++_C++11_Move Semantics_Rvalue Reference - Fatal编程技术网

C++ 通过std::function<;安全吗;bool(标准::字符串)>&&;回调(即作为右值移动)及其效果如何?

C++ 通过std::function<;安全吗;bool(标准::字符串)>&&;回调(即作为右值移动)及其效果如何?,c++,c++11,move-semantics,rvalue-reference,C++,C++11,Move Semantics,Rvalue Reference,给定以下工作代码(main.cpp): #包括 #包括 结构工人 { std::函数m_回调; void do_work(std::function callback)//如果参数定义为右值引用,则必须向右值传递临时值或强制转换左值,如使用std::move() 右值引用的语义是调用方应该期望传递的参数被掠夺,使其有效但任意,这意味着大部分是无用的 但是,接收右值引用的函数,尽管有掠夺的许可证,也没有掠夺的义务。如果它没有明确这样做,例如通过传递该许可证,那么它就不会通过,也不会发生任何特殊情况

给定以下工作代码(main.cpp):

#包括
#包括
结构工人
{
std::函数m_回调;

void do_work(std::function callback)//如果参数定义为右值引用,则必须向右值传递临时值或强制转换左值,如使用
std::move()

右值引用的语义是调用方应该期望传递的参数被掠夺,使其有效但任意,这意味着大部分是无用的

但是,接收右值引用的函数,尽管有掠夺的许可证,也没有掠夺的义务。如果它没有明确这样做,例如通过传递该许可证,那么它就不会通过,也不会发生任何特殊情况

您的代码就是这样一种情况


虽然我会从我的词汇表中禁止
std::bind
,但使用与否实际上没有任何显著区别。

如果参数定义为右值引用,则必须传递临时值或将左值强制转换为右值,如
std::move()

右值引用的语义是调用方应该期望传递的参数被掠夺,使其有效但任意,这意味着大部分是无用的

但是,接收右值引用的函数,尽管有掠夺的许可证,也没有掠夺的义务。如果它没有明确这样做,例如通过传递该许可证,那么它就不会通过,也不会发生任何特殊情况

您的代码就是这样一种情况


虽然我会从我的词汇表中禁止
std::bind
,但使用与否实际上没有任何显著的区别。

在这种情况下,无论是通过值传递还是通过rval引用传递,都必须创建一个临时std::函数,这是因为lambda实际上不是std::函数。在任何情况下,都应该移动std::f在分配之前,请关闭该功能,以避免制作不必要的副本。

在这种情况下,我建议按值传递,因为这有点灵活,如果传递lambda,那么它不会造成任何伤害,因为std::函数通常会被构造到位(因此临时值不会被移动到函数中;这种移动可以而且通常会被省略).

在这种情况下,无论您是通过值传递还是通过rval ref传递,都必须创建临时std::函数,这是因为lambda实际上不是std::函数。在任何情况下,您都应该在赋值之前移动std::函数,以避免生成不必要的副本。

在这种情况下,我建议按值传递,因为这有点灵活,如果传递lambda,那么它不会造成任何伤害,因为std::函数通常会被构造到位(因此临时值不会被移动到函数中;这种移动可以而且通常会被省略).

你不需要
std::bind
调用,只要赋值
m_callback=callback;
@Someprogrammerdude我知道-你只需要原谅这个蹩脚的例子就行了!(很难做一个简单的例子来说明一点,而不做蹩脚的代码)…但我确实想以这种方式传递和存储回调(即使用lambda或bind)。我只想专注于传递类型(即按值或按
&&
)。您不需要
std::bind
调用,只需要赋值
m_callback=callback;
@我认识的某个编程人员-您必须原谅这个糟糕的示例!(很难制作一个简单的示例来展示一个点而不生成垃圾代码)…但我确实希望以这种方式传递和存储回调(即使用lambda或bind)。我只想关注传递类型(即通过值或通过
&&
)。我正在反复阅读你写的单词,但我觉得我太简单了,无法理解。我想我理解你对
std::move()
-这意味着如果它是左值(像对象之类的),那么你就移动它。你能像我是个孩子一样解释最后一部分吗,比如:在我的代码中,这两种情况下会发生什么(即,它确实被移动了吗?)。谢谢:)不,它不会被移动,因为即使您在某些点上使用右值引用,您也不会在任何地方使用它们,因为它们会导致行为的改变,也就是导致对象被移动。出于好奇,您对
std::bind
有什么问题?您是指它的所有用法还是仅指传递函数的用法(即第二个)?@code\u foeder:
std::bind
的问题是lambda既更干净,有时可能更高效。诚然,
std::bind
的优点是重复为相同的参数生成相同的类型,而不是对每种情况都是唯一的。好的,谢谢,我只是检查了没有什么明显不好的问题关于它-你只是说它已经被lambdas有效地淘汰了:)我正在反复阅读你写的单词,但我觉得我太简单了,无法理解它!我想我理解你对
std::move()
-这意味着如果它是左值(像对象之类的?)然后你移动它。你能像我是个孩子一样解释最后一部分吗,比如:在我的代码中的两种情况下会发生什么(例如,它真的移动了吗?)。谢谢:)不,它不会被移动,因为即使您在某些点上使用右值引用,您也不会在任何地方使用它们,因为它们会导致行为的改变,也就是导致对象被移动。出于好奇,您对
std::bind
有什么问题?您是指它的所有用法还是仅指传递函数的用法(即第二个)@code\u foeder:我对
std::bind
的问题是lambda更干净,有时可能更高效。诚然,
std::bind
的优点是重复为相同的参数生成相同的类型
#include <functional>
#include <iostream>

struct worker
{
   std::function<bool(std::string)> m_callback;
   void do_work(std::function<bool(std::string)> callback) // <--- this line
   {
      m_callback = std::bind(callback, std::placeholders::_1);
      callback("hello world!\n");
   }
};


// pretty boring class - a cut down of my actual class
struct helper
{
   worker the_worker;
   bool work_callback(std::string str)
   {
      std::cout << str << std::endl;
      return false;
   }
};

int main()
{
   helper the_helper;
   the_helper.the_worker.do_work( [&](std::string data){ return the_helper.work_callback(data); });
}