use_count () из shared_ptr переместился в std :: async в gcc 4.6.3

В приведенном ниже коде я хочу use_count() из shared_ptr переехал в std::async быть 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?

2

Решение

возможный обходной путь может быть

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 делает дополнительную копию в исходном коде; кажется, что временное значение, данное decay_copy в async (), не передается параметру fun () в качестве значения r, как должно быть. Разве вы не можете войти со своим отладчиком, чтобы увидеть, что происходит?

1

Другие решения

Хотя 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();
}
0

По вопросам рекламы [email protected]