5

私はC++でマルチスレッドプログラミングについてもっと試してみましたが、理解するのに苦労しstd::promiseていたので、このWebサイトで答えを探し始めました。しかし、答えを読んでさらに混乱しました。これは、おそらく同様の実装である答えのコードですstd::packaged_task

template <typename> class my_task;

template <typename R, typename ...Args>
class my_task<R(Args...)>
{
    std::function<R(Args...)> fn;
    std::promise<R> pr;             // the promise of the result
public:
    template <typename ...Ts>
    explicit my_task(Ts &&... ts) : fn(std::forward<Ts>(ts)...) { }

    template <typename ...Ts>
    void operator()(Ts &&... ts)
    {
        pr.set_value(fn(std::forward<Ts>(ts)...));  // fulfill the promise
    }

    std::future<R> get_future() { return pr.get_future(); }

    // disable copy, default move
};

このコードでは、

1- この構文の意味template <typename R, typename ...Args> class my_task<R(Args...)>、より具体的には、 の目的は<R(Args...)>何ですか?

2-クラスの前方宣言があるのはなぜですか?

ありがとう

4

2 に答える 2

5

コメントでは、1 と 2 を 2 つの別々の質問にする方法について簡単な議論がありましたが、次の理由から、どちらもまったく同じ質問の 2 つの側面にすぎないと思います。

template <typename> class my_task;

template <typename R, typename ...Args>
class my_task<R(Args...)>; ....

typename最初のステートメントは、唯一のテンプレート パラメーターとしてa を取るテンプレートを宣言します。2 番目のステートメントは、そのテンプレート クラスの特殊化を宣言します。

この文脈では:

 R(Args...)

typename関数に一致するものに特化します。このテンプレートの特殊化は、 の関数シグネチャを渡すテンプレートのインスタンス化と一致しますtypename。テンプレート自体に問題がなければ、このテンプレートの特殊化は次の目的で使用されます。

 my_task<int (const char *)>

または、const char *パラメータを取り、 を返す関数int。テンプレートの特殊化も一致します。

 my_task<Tptr *(Tptr **, int)>

または、2 つのパラメーターと を取り、 を返す関数Tptr **(intここTptr *Tptrは、他のクラス)。

テンプレートの特殊化は一致しません:

 my_task<int>

または

 my_task<char *>

それらは関数シグネチャではないためです。関数以外を使用してこのテンプレートをインスタンス化しようとするとtypename、コンパイル エラーが発生します。なんで?

これは、テンプレートが定義されていないためです。

template<typename> class my_task;

これを単なる前方宣言と考えないでください。これはテンプレート パラメーターを受け取るテンプレートの前方宣言であり、テンプレートはどこにも定義されません。むしろ、テンプレート宣言は、テンプレート パラメーターとして渡された特定の型のみに一致する後続のテンプレート特殊化宣言を許可します。

これは、特定のテンプレートで使用できるtypenames またはesの種類を制限するための一般的なプログラミング手法です。テンプレートを任意のまたはclassだけで使用できるようにする代わりに、テンプレートは一部のサブセットでのみ使用できます。この場合、関数または署名です。typenameclasstypename

また、テンプレート自体が (この場合は) テンプレート パラメーターの戻り値の型とパラメーターの型を明示的に参照しやすくなります。テンプレートに単純な単一typenameのテンプレート パラメーターしかない場合、関数の戻り値の型や関数パラメーターの型に簡単にアクセスできません。

于 2015-12-02T02:22:26.697 に答える