use_count() 的shared_ptr在 gcc 4.6.3 中移动到 std::async 中



在下面的代码中,我希望移动到std::async中的shared_ptruse_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();
}

相关内容

  • 没有找到相关文章

最新更新