- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
当我使用 Boost.Asio 时,创建诸如 ip::tcp::socket
或 deadline_timer
之类的对象作为 std::shared_ptr
和将其作为 lambda 表达式复制到完成处理程序。
我很好奇如果我使用移动捕捉而不是复制捕捉会发生什么。我认为这很危险。在下面的示例中,我认为 tim = std::move(tim)
在 tim->async_wait
之前被求值。所以 tim 不再有有效的指针。这是我的猜测。为了跟踪 std::shared_ptr
的行为,我创建了 std::shared_ptr
包装器 shared_ptr
。
#include <iostream>
#include <boost/asio.hpp>
namespace as = boost::asio;
template <typename... Args>
struct shared_ptr : std::shared_ptr<Args...> {
using base = std::shared_ptr<Args...>;
using base::base; // inheriting constructor
shared_ptr(shared_ptr&& other) : base(std::move(other)) {
std::cout << "move" << std::endl;
}
typename base::element_type* operator->() {
std::cout << "->" << std::endl;
return base::get();
}
};
int main() {
as::io_context ioc;
ioc.post(
[&] {
shared_ptr<as::deadline_timer> tim(new as::deadline_timer(ioc));
tim->expires_from_now(boost::posix_time::seconds(1));
tim->async_wait(
// I think that it is dangerous because tim has been moved before tim->async_wait()
[&, tim = std::move(tim)]
std::cout << ec.message() << std::endl;
}
);
}
);
ioc.run();
}
我在几个环境中运行代码:
所有选项都是-std=c++14
g++ 7.1.0 或更高版本:https://wandbox.org/permlink/rgJLp66vH7jKodQ8一个
g++ 6.3.0:https://wandbox.org/permlink/XTIBhjJSqmkQHN4P B
clang++ 4.0.1~:https://wandbox.org/permlink/nEZpFV874pKstjHA一个
输出A
->
->
move
move
move
move
Success
输出 B
->
move
->
Segmentation fault
似乎 clang++ 和 g++ 7.1.0 或更高版本首先评估 tim->async_wait()
。
g++ 6.3.0 首先评估 tim = std::move(tim)
。
这是未定义的行为吗?或者评估顺序是在某个时候定义的?
最佳答案
C++17 中的评估顺序是明确定义的,例如 the expression leading to the function call (tim->async_wait
) is sequenced before any of its arguments .
C++14 但是,由于 lack of such sequencing rules,这是未指定的.也就是说,它可能有效,也可能无效,并且不需要实现来告诉您它选择的方式,甚至不需要在一次调用与另一次调用之间保持一致。
关于c++ - lambda表达式移动捕获的时机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57108220/
我是一名优秀的程序员,十分优秀!