shared_ptr的use_count()移入gcc 4.6.3中的std :: async

时间:2017-11-01 15:16:48

标签: c++ c++11 shared-ptr stdasync std-future

在下面的代码中,我希望移到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升级我的编译器?

2 个答案:

答案 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();
}