読者です 読者をやめる 読者になる 読者になる

future::share()は何のためにあるのか

C++

std::futureクラスには、share()というメンバ関数があります。この関数は、futureオブジェクトを、複数インスタンスで非同期処理の待機と結果取得を行うstd::shared_futureクラスのオブジェクトに変換するための関数です。

#include <iostream>
#include <future>
#include <thread>
#include <mutex>

std::mutex mtx_;
void print(int x)
{
    std::lock_guard<std::mutex> lk(mtx_);
    std::cout << x << std::endl;
}

void foo(std::shared_future<int> f)
{
    print(f.get());
}

void bar(std::shared_future<int> f)
{
    print(f.get());
}

int main()
{
    std::shared_future<int> f = std::async(std::launch::async, [] { return 3; }).share(); // これ
    std::thread t1(foo, f);
    std::thread t2(bar, f);

    t1.join();
    t2.join();
}
3
3

しかし、std::shared_futureクラスはそれ自体がstd::futureからの変換コンストラクタを持っているので、実はこの関数はなくてもよかったりします。

#include <iostream>
#include <future>
#include <thread>
#include <mutex>

std::mutex mtx_;
void print(int x)
{
    std::lock_guard<std::mutex> lk(mtx_);
    std::cout << x << std::endl;
}

void foo(std::shared_future<int> f)
{
    print(f.get());
}

void bar(std::shared_future<int> f)
{
    print(f.get());
}

int main()
{
    std::shared_future<int> f = std::async(std::launch::async, [] { return 3; }); // share()を使わない
    std::thread t1(foo, f);
    std::thread t2(bar, f);

    t1.join();
    t2.join();
}
3
3

では、このshare()メンバ関数は何のためにあるかというと、autoのためにあるようです。

#include <iostream>
#include <future>
#include <thread>
#include <mutex>

std::mutex mtx_;
void print(int x)
{
    std::lock_guard<std::mutex> lk(mtx_);
    std::cout << x << std::endl;
}

void foo(std::shared_future<int> f)
{
    print(f.get());
}

void bar(std::shared_future<int> f)
{
    print(f.get());
}

int main()
{
    auto f = std::async(std::launch::async, [] { return 3; }).share();
    std::thread t1(foo, f);
    std::thread t2(bar, f);

    t1.join();
    t2.join();
}
3
3


参照:
future::share() - cpprefjp
shared_future - cpprefjp