在下面的代码中,我希望移到use_count()
的{{1}}的{{1}}为shared_ptr
:
std::async
我的平台使用gcc 4.6.3,上面的代码给出了这个输出(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)
);
}
在coliru.stacked-crooked.com上,我得到了我想要的行为(fun: sp.use_count() == 2
):
fun: sp.use_count() == 2 (in gcc 4.6.3, is there a way to make this 1?)
我不确定编译器coliru使用的是什么,但我猜它比gcc 4.6.3更新。
有没有办法,一些解决方法,以获得我想要的行为,而无需从gcc 4.6.3升级我的编译器?
答案 0 :(得分:1)
可能的解决方法可能是
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()参数作为它应该的rvalue。您是否可以介入调试器以查看正在进行的操作?
答案 1 :(得分:0)
虽然std::async
创建了所有参数的副本,但是在调用函数时它会完美地将参数转发给callable,以便保留参数值类别。
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();
}