传递参数为std ::异步引用失败 [英] Passing arguments to std::async by reference fails

查看:168
本文介绍了传递参数为std ::异步引用失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我注意到,这是不可能通过一个非const引用作为参数传递给的std ::异步

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 ::的reference_wrapper 包传递到的std ::异步的价值,一切都OK 。我想这是因为的std ::异步需要它的通过值参数,但我还是不明白错误的原因。

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.

首先,它并不一定能找出functionoid是否传递到异步引用或不接受它的参数。 (如果它不是一个简单的功能,但一个函数对象,它可能有一个重载函数调用操作,例如。)因此,异步不能说,嘿,让我检查什么样的目标函数想,我会做正确的事。

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.

但随后,该机制是这么写的,它实际上没有那么参数传递给非const左值引用参数。这是出于安全的另一种选择。否则,你会希望修改原来的左值,而不是修改副本的功能,导致这都很难的bug跟踪

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.

但是,如果你真的想非const左值引用参数?如果你答应什么注意悬挂引用和比赛条件?这就是性病::裁判是。这是一个明确的选择,在对危险的引用语义。这是你说的办法:我知道我在做什么了。

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 ::异步引用失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆