2017-01-19 9 views
0

私はタプルを書くことを実験していますが、私が理解していないことは、スワップを書く方法です。 (簡体字)のタイプは次のようになります。私は// ???でマークされた場所での指標と種類を展開しようとしてきたが、どのように私の人生のために把握することはできませんバリデーション基底クラスでスワップ

template<size_t I, typename T> 
struct tuple_elem { 
    ... 

    void swap(tuple_elem& other) 
    { 
     // implemented 
    } 
}; 

template<size_t... Is, typename... Ts> 
struct tuple_impl<std::index_sequence<Is...>, Ts...> 
    : private tuple_elem<Is, Ts>... 
{ 
    void swap(tuple_impl& other) 
    { 
     // ??? 
    } 
}; 

。私は次のようなものを試してみた:

static_cast<tuple_elem<Is, Ts>&>(*this)->swap(
      static_cast<tuple_elem<Is, Ts>&>(other))...; 

しかし、のようなエラーを与えた:

Tuple.hpp:182:64: error: expected ';' before '...' token 
       static_cast<tuple_elem<Is, Ts>&>(other))...; 
                 ^~~ 
Tuple.hpp:182:67: error: parameter packs not expanded with '...': 
       static_cast<tuple_elem<Is, Ts>&>(other))...; 
                  ^

ヘルプ!

+0

swap(static_cast (* this)、static_cast (other))、...のようなものでしょうか?たぶん、ダミーの配列のインネイザを使用しています。 –

+0

@KerrekSBああ、ダミーの配列はそのトリックです。しかし、それがよりエレガントにできるかどうか疑問に思っています。 –

+0

C++ 17では、これは非常に素晴らしく読みやすいように折り畳み式をしています。 –

答えて

0

さて、まずは。あなたが試したようにパックを拡張することで、有効な式を得ることはできません。それを書き出してみてください。

ここから簡単に始めます。 (あなたはstd::tupleが持っている標準ユーティリティのいくつかを持っているので、私は、あなたがタプルを実装しようとしていると仮定しています。)あなたのコンパイラは、C++ 17の折り畳み式を実装する場合、スワップは同じくらい簡単として行うことができます。

template<typename... Tn, typename... Tn2, size_t... Is> 
void swap_impl(tuple<Tn...>& a, tuple<Tn2...>& b, std::index_sequence<Is...>) 
{ 
    using std::swap; 
    (swap(get<Is>(a), get<Is>(b)), ...); 
} 

は2つのタプルで呼び出され、std::index_sequence_for<Is...>{}で呼び出されます。 get<I>(tuple)は実装が簡単ですが、あなたのstatic_cast<tuple_elem<Is, Ts>&>(tuple)のものです。一方

あなたが唯一のC++ 14へのアクセス権を持っている場合は、私のアプローチは、次のようになります。任意の再帰的な方法と同様に明らかに

template<size_t N> 
struct tuple_ops 
{ 
    template<typename T, typename T2, size_t I = tuple_size<T>::value - N> 
    static constexpr void swap(T& a, T2& b) 
    { 
     using std::swap; 
     swap(get<I>(a), get<I>(b)); 
     return tuple_ops<N - 1>::swap(a, b); 
    } 
}; 

、あなたがのための基本ケースを提供する必要があると思いますが0

template<> 
struct tuple_ops<0> 
{ 
    template<typename T, typename T2> 
    static constexpr void swap(T&, T2&) noexcept {} 
}; 

その後、あなたのスワップ機能は次のようになります。

constexpr void swap(tuple& rhs) { 
    tuple_ops<sizeof...(Tn)>::swap(*this, rhs); 
} 

注:コードがテストされていません。

関連する問題