在下面的代码中,我希望移动到std::async
中的shared_ptr
的use_count()
1
:
#include <memory>
#include <iostream>
#include <future>
using namespace std;
void fun(shared_ptr<int> sp)
{
cout << "fun: sp.use_count() == " << sp.use_count() <<
" (in gcc 4.6.3, is there a way to make this 1?)n";
}
int main()
{
auto sp1 = make_shared<int>(5);
auto fut = async(
launch::async,
fun,
move(sp1)
);
}
我的平台使用 gcc 4.6.3,上面的代码给出了这个输出 ( fun: sp.use_count() == 2
):
fun: sp.use_count() == 2 (in gcc 4.6.3, is there a way to make this 1?)
在 coliru.stacked-crooked.com 上,我得到了我想要的行为(fun: sp.use_count() == 1
):
fun: sp.use_count() == 1 (in gcc 4.6.3, is there a way to make this 1?)
我不确定 coliru 使用的是什么编译器,但我猜它比 gcc 4.6.3 更新。
有没有办法,一些解决方法,以获得我想要的行为,而不必从gcc 4.6.3升级我的编译器?
可能的解决方法可能是
void fun(shared_ptr<int>* sp)
{
unique_ptr<shared_ptr<int>> guard(sp);
cout << "fun: sp.use_count() == " << sp->use_count() <<
" (in gcc 4.6.3, is there a way to make this 1?)n";
}
int main()
{
auto sp1 = make_shared<int>(5);
auto fut = async(
launch::async,
fun,
new shared_ptr<int>(move(sp1))
);
}
也就是说,看看 gcc463 在原始代码中在哪里制作额外的副本会很有趣;似乎 async() 中 decay_copy 给出的临时没有作为右值转发到 fun() 的参数。您不能使用调试器查看发生了什么吗?
尽管std::async
会复制所有参数,但在调用函数时,它会将参数完美转发到可调用对象,以便保留参数值类别。
要std::async
的参数只需要是 MoveConstructible,否则将无法std::unique_ptr
传递到 std::async
中。
换句话说,正确的行为是sp.use_count() == 1
的,这就是我在旧的 g++-5.3.1 中观察到的。
检查以下代码是否与您观察到sp.use_count() == 2
的编译器一起编译:
using namespace std;
void fun(unique_ptr<int> p) {
cout << "fun " << *p << 'n';
}
int main() {
unique_ptr<int> sp(new int{1});
auto fut = async(
launch::async,
fun,
move(sp)
);
fut.get();
}