4

次のように stl タプルを使用して、いくつかの変数の保存/復元機能を実装しています。

double a = 1, b = 2;
int c = 3;
auto tupleRef = std::make_tuple(std::ref(a), std::ref(b), std::ref(c));

// here I'm saving current state of a, b, c
std::tuple<double, double, int> saved = tupleRef;

//here goes block of code, where a, b, and c get spoiled
......................
//

//now I'm restoring initial state of a, b, c
tupleRef = savedTuple;

このコードはうまく機能します。ただし、明示的にタプル メンバー タイプを指定する代わりに、

std::tuple<double, double, int> saved = tupleRef;

次のように、すべての tupleRef メンバーから参照を削除したいと思います。

auto saved = remove_ref_from_tuple_members(tupleRef);

そのために「remove_ref_from_tuple_members」テンプレートを書くことは可能だと思います。

回答ありがとうございます。

4

2 に答える 2

7

単純な型エイリアスを使用しstd::remove_referenceて、タプル内のすべての型に適用できます。

template <typename... T>
using tuple_with_removed_refs = std::tuple<typename std::remove_reference<T>::type...>;

これで武装して、関数テンプレートを書くことができます:

template <typename... T>
tuple_with_removed_refs remove_ref_from_tuple_members(std::tuple<T...> const& t) {
    return tuple_with_removed_refs { t };
}
于 2012-10-05T09:03:41.247 に答える
0

R. Martinho Fernandesに感謝します。そのコードは、Visual Studioでコンパイルするように変更できました。ここでは、タプルが10種類のテンプレートとしてハードコーディングされており、未使用の型は空の構造体です。

#define _RR_(x) typename std::remove_reference<x>::type
#define _no_ref_tuple_  std::tuple<_RR_(T0), _RR_(T1), _RR_(T2), _RR_(T3), _RR_(T4), _RR_(T5), _RR_(T6), _RR_(T7), _RR_(T8), _RR_(T9)>

template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
_no_ref_tuple_ map_remove_ref(std::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> const& t) 
{
    return _no_ref_tuple_(t);
}

また、refをタプルにバインドするのは

auto tupleRef = std::make_tuple(std::ref(x_0), ..., std::ref(x_n));

冗長性を減らすことができます:

auto tupleRef = std::forward_as_tuple(x_0, ..., x_n);

ただし、std :: forward_as_tupleがないため、これもVSでは機能しません。

于 2012-10-08T08:57:56.500 に答える