- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有一个函数模板,我想在其中完美转发到我在另一个线程上运行的 lambda。这是您可以直接编译的最小测试用例:
#include <thread>
#include <future>
#include <utility>
#include <iostream>
#include <vector>
/**
* Function template that does perfect forwarding to a lambda inside an
* async call (or at least tries to). I want both instantiations of the
* function to work (one for lvalue references T&, and rvalue reference T&&).
* However, I cannot get the code to compile when calling it with an lvalue.
* See main() below.
*/
template <typename T>
std::string accessValueAsync(T&& obj)
{
std::future<std::string> fut =
std::async(std::launch::async,
[](T&& vec) mutable
{
return vec[0];
},
std::forward<T>(obj));
return fut.get();
}
int main(int argc, char const *argv[])
{
std::vector<std::string> lvalue{"Testing"};
// calling with what I assume is an lvalue reference does NOT compile
std::cout << accessValueAsync(lvalue) << std::endl;
// calling with rvalue reference compiles
std::cout << accessValueAsync(std::move(lvalue)) << std::endl;
// I want both to compile.
return 0;
}
对于非编译情况,这里是可以理解的错误消息的最后一行:
main.cpp|13 col 29| note: no known conversion for argument 1 from ‘std::vector<std::basic_string<char> >’ to ‘std::vector<std::basic_string<char> >&’
我感觉这可能与 T&&
的推导方式有关,但我无法确定确切的故障点并修复它。有什么建议吗?
谢谢!
编辑:我正在使用 gcc 4.7.0 以防万一这可能是编译器问题(可能不是)
最佳答案
根据我的理解,您不能通过 async
使用函数期望非常量左值引用作为参数,因为 async
将始终在内部制作它们的拷贝(或将它们移动到内部)以确保它们存在并且在创建的线程的整个运行时间内有效。
具体来说,标准说的是 async(launch policy, F&& f, Args&&... args)
:
(§30.6.8)
(2) Requires:
F
and eachTi
inArgs
shall satisfy the MoveConstructible requirements.INVOKE(DECAY_COPY (std::forward<F>(f)), DECAY_COPY (std::forward<Args>(args))...)
(20.8.2, 30.3.1.2) shall be a valid expression.(3) Effects: [...] if policy & launch::async is non-zero — calls
INVOKE(DECAY_COPY (std::forward<F>(f)),DECAY_COPY (std::forward<Args>(args))...)
(20.8.2, 30.3.1.2) as if in a new thread of execution represented by a thread object with the calls toDECAY_COPY()
being evaluated in the thread that called async. Any return value is stored as the result in the shared state. Any exception propagated from the execution of INVOKE (DECAY_COPY (std::forward(f)), DECAY_COPY (std::forward(args))...) is stored as the exceptional result in the shared state.
The thread object is stored in the shared state and affects the behavior of any asynchronous return objects that reference that state.
不幸的是,这意味着您甚至无法将引用替换为 std::reference_wrapper
,因为后者不可移动构造。我想使用 std::unique_ptr
而不是引用会起作用(但是,这意味着您的函数参数将始终存在于堆中)。
(编辑/更正)
当我意识到 std::reference_wrapper
时,我正在研究相关问题实际上启用了一个解决方法,尽管我在上面声称相反。
如果你定义了一个将左值引用包装在 std::reference_wrapper
中的函数, 但保留右值引用不变,您可以传递 T&&
在将其移交给 std::async
之前通过此函数进行论证.我调用了这个特殊的包装函数 wrap_lval
下面:
#include <thread>
#include <future>
#include <utility>
#include <iostream>
#include <vector>
#include <type_traits>
/* First the two definitions of wrap_lval (one for rvalue references,
the other for lvalue references). */
template <typename T>
constexpr T&&
wrap_lval(typename std::remove_reference<T>::type &&obj) noexcept
{ return static_cast<T&&>(obj); }
template <typename T>
constexpr std::reference_wrapper<typename std::remove_reference<T>::type>
wrap_lval(typename std::remove_reference<T>::type &obj) noexcept
{ return std::ref(obj); }
/* The following is your code, except for one change. */
template <typename T>
std::string accessValueAsync(T&& obj)
{
std::future<std::string> fut =
std::async(std::launch::async,
[](T&& vec) mutable
{
return vec[0];
},
wrap_lval<T>(std::forward<T>(obj))); // <== Passing obj through wrap_lval
return fut.get();
}
int main(int argc, char const *argv[])
{
std::vector<std::string> lvalue{"Testing"};
std::cout << accessValueAsync(lvalue) << std::endl;
std::cout << accessValueAsync(std::move(lvalue)) << std::endl;
return 0;
}
通过此更改,两次调用 accessValueAsync
编译和工作。第一个使用左值引用,自动将其包装在 std::reference_wrapper
中。 .后者在 std::async
时自动转换回左值引用调用 lambda 函数。
关于c++ - 完美转发到异步 lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13813838/
可以使用 lambda 和函数创建有序对(Lisp 中的缺点),如 Use of lambda for cons/car/cdr definition in SICP 所示。 它也适用于 Python
我正在尝试从另一个调用一个 AWS lambda 并执行 lambda 链接。这样做的理由是 AWS 不提供来自同一个 S3 存储桶的多个触发器。 我创建了一个带有 s3 触发器的 lambda。第一
根据以下源代码,常规 lambda 似乎可以与扩展 lambda 互换。 fun main(args: Array) { val numbers = listOf(1, 2, 3) f
A Tutorial Introduction to the Lambda Calculus 本文介绍乘法函数 The multiplication of two numbers x and y ca
我想弄清楚如何为下面的表达式绘制语法树。首先,这究竟是如何表现的?看样子是以1和2为参数,如果n是 0,它只会返回 m . 另外,有人可以指出解析树的开始,还是一个例子?我一直找不到一个。 最佳答案
在 C++0x 中,我想知道 lambda 函数的类型是什么。具体来说: #include type1 foo(int x){ return [x](int y)->int{return x * y
我在其中一个职位发布中看到了这个问题,它询问什么是 lambda 函数以及它与高阶函数的关系。我已经知道如何使用 lambda 函数,但不太自信地解释它,所以我做了一点谷歌搜索,发现了这个:What
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
Evaluate (((lambda(x y) (lambda (x) (* x y))) 5 6) 10) in Scheme. 我不知道实际上该怎么做! ((lambda (x y) (+ x x
我正在处理 MyCustomType 的实例集合如下: fun runAll(vararg commands: MyCustomType){ commands.forEach { it.myM
Brian 在他对问题 "Are side effects a good thing?" 的论证中的前提很有趣: computers are von-Neumann machines that are
在 Common Lisp 中,如果我希望两个函数共享状态,我将按如下方式执行 let over lambda: (let ((state 1)) (defun inc-state () (in
Evaluate (((lambda(x y) (lambda (x) (* x y))) 5 6) 10) in Scheme. 我不知道实际上该怎么做! ((lambda (x y) (+ x x
作为lambda calculus wiki说: There are several possible ways to define the natural numbers in lambda cal
我有一个数据类,我需要初始化一些 List .我需要获取 JsonArray 的值(我使用的是 Gson)。 我做了这个函数: private fun arrayToList(data: JsonAr
((lambda () )) 的方案中是否有简写 例如,代替 ((lambda () (define x 1) (display x))) 我希望能够做类似的事情 (empty-lam
我在 Java library 中有以下方法: public void setColumnComparator(final int columnIndex, final Comparator colu
我正在研究一个函数来计算国际象棋游戏中棋子的有效移动。 white-pawn-move 函数有效。当我试图将其概括为任一玩家的棋子 (pawn-move) 时,我遇到了非法函数调用。我已经在 repl
考虑这段代码(在 GCC 和 MSVC 上编译): int main() { auto foo = [](auto p){ typedef decltype(p) p_t;
我正在阅读一个在 lambda 内部使用 lambda 的片段,然后我想通过创建一个虚拟函数来测试它,该函数从文件中读取然后返回最大和最小数字。 这是我想出来的 dummy = lambda path
我是一名优秀的程序员,十分优秀!