9

だから私はこれがどのように機能するかを理解しようとしています: C++11: 複数の引数からタプルに移動できますが、タプルから複数の引数に移動できますか?

私が理解できない黒魔術の一部は、次のコードの一部です。

f(std::get<N>(std::forward<Tuple>(t))...)

fわからないのは中の表現です。

式が何らかの形で内容tを引数のリストに展開/展開することを理解しています。しかし、誰かがこれがどのように行われるかを説明できますか? std::gethttp://en.cppreference.com/w/cpp/utility/tuple/get )の定義を見ると、どのようNに収まるかわかりません...?私が知る限り、N は整数のシーケンスです。

私が観察できることに基づいて、式はE<X>...where Xis the sequence of typesという形式であると想定していますX1X2、... Xn、式は として展開されE<X1>, E<X2> ... E<Xn>ます。これが仕組みですか?

編集:この場合、 N は型のシーケンスではなく、整数です。しかし、この言語構​​造は型と値の両方に当てはまると思います。

4

2 に答える 2

2

を展開するための基本的な構成要素std::tuple<T...>は、実際にはコードから省略されています。2 番目のパラメーターを取得するstd::tuple<...>必要があります0, 1, ..., n。これら 2 つのパラメーター パックを取得したら、それらを連携して展開できます。

template <typename F, typename... T, int... N>
void call_impl(F&& fun, std::tuple<T...>&& t) {
    fun(std::get<N>(t)...);
}

本当の魔法は、std::tuple<T...>. テンプレートプログラミングが少し必要です。インデックスのリストを作成する方法は次のとおりです。

template <int... Indices> struct indices;
template <> struct indices<-1> { typedef indices<> type; };
template <int... Indices>
struct indices<0, Indices...>
{
    typedef indices<0, Indices...> type;
};
template <int Index, int... Indices>
struct indices<Index, Indices...>
{
    typedef typename indices<Index - 1, Index, Indices...>::type type;
};

template <typename T>
typename indices<std::tuple_size<T>::value - 1>::type const*
make_indices()
{
    return 0;
}

call()したがって、関数テンプレートがある場合は、関数オブジェクトと関数std::tuple<T...>への引数を持つ を受け取る関数テンプレートを呼び出しましょう。簡単なアプローチはcall_impl()、インデックスの推定に対処するために上記を書き直すことです。

template <typename F, typename Tuple, int... N>
void call_impl(F&& fun, Tuple&& t, indices<Indices...> const*)
{
    fun(std::get<N>(t)...);
}

template <typename F, typename Tuple>
void call(F&& fun, Tuple&& t)
{
    call_imle(std::forward<F>(fun), std::forward<Tuple>(t), make_indices<Tuple>());
}

このコードが実際に拡張していないのは、関数を呼び出すときstd::forward<...>()のさまざまな要素での正しい使用です。要素を移動するのではなく、全体を移動する可能性があるため、std::tuple<...>使用するだけでstd::forward<Tuple>(t)は機能しません。a の適切な要素ごとの移動のようなことができるとstd::tuple<...>思いますstd::tuple<...>が、まだ行っていません。

于 2013-09-24T22:37:52.850 に答える