Passing arguments to std::async by reference fails(通过引用将参数传递给 std::async 失败)
问题描述
我注意到不可能将非常量引用作为参数传递给 std::async
.
I've noticed that it's impossible to pass a non-const reference as an argument to std::async
.
#include <functional>
#include <future>
void foo(int& value) {}
int main() {
int value = 23;
std::async(foo, value);
}
我的编译器 (GCC 4.8.1) 在这个例子中给出了以下错误:
My compiler (GCC 4.8.1) gives the following error for this example:
error: no type named ‘type’ in ‘class std::result_of<void (*(int))(int&)>’
但是如果我将传递给 std::async
的值包装在 std::reference_wrapper
中,则一切正常.我认为这是因为 std::async
按值获取它的参数,但我仍然不明白错误的原因.
But if I wrap the value passed to std::async
in std::reference_wrapper
, everything is OK. I assume this is because std::async
takes it's arguments by value, but I still don't understand the reason for the error.
推荐答案
这是一个深思熟虑的设计选择/权衡.
It's a deliberate design choice/trade-off.
首先,不一定能够确定传递给 async
的 functionoid 是否通过引用获取其参数.(如果它不是一个简单的函数而是一个函数对象,例如,它可能有一个重载的函数调用运算符.)所以 async
不能说,嘿,让我检查一下目标函数想要什么,我会做正确的事."
First, it's not necessarily possible to find out whether the functionoid passed to async
takes its arguments by reference or not. (If it's not a simple function but a function object, it could have an overloaded function call operator, for example.) So async
cannot say, "Hey, let me just check what the target function wants, and I'll do the right thing."
所以设计问题是,如果可能的话,它是否通过引用获取所有参数(即如果它们是左值),还是总是复制?制作副本是这里安全的选择:副本不能成为悬空,副本不能表现出竞争条件(除非它真的很奇怪).所以这就是做出的选择:默认情况下复制所有参数.
So the design question is, does it take all arguments by reference if possible (i.e. if they're lvalues), or does it always make copies? Making copies is the safe choice here: a copy cannot become dangling, and a copy cannot exhibit race conditions (unless it's really weird). So that's the choice that was made: all arguments are copied by default.
但是,该机制被编写为实际上无法将参数传递给非常量左值引用参数.这是安全的另一种选择:否则,您希望修改原始左值的函数会修改副本,从而导致很难追踪的错误.
But then, the mechanism is written so that it actually fails to then pass the arguments to a non-const lvalue reference parameter. That's another choice for safety: otherwise, the function that you would expect to modify your original lvalue instead modifies the copy, leading to bugs that are very hard to track down.
但是如果您真的非常想要非常量左值引用参数怎么办?如果您承诺注意悬空引用和竞争条件怎么办?这就是 std::ref
的用途.这是对危险参考语义的明确选择.这是你的表达方式,我知道我在这里做什么."
But what if you really, really want the non-const lvalue reference parameter? What if you promise to watch out for dangling references and race conditions? That's what std::ref
is for. It's an explicit opt-in to the dangerous reference semantics. It's your way of saying, "I know what I'm doing here."
这篇关于通过引用将参数传递给 std::async 失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:通过引用将参数传递给 std::async 失败
基础教程推荐
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 从 std::cin 读取密码 2021-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01