3

の射影関数を探していstd::tupleます。つまり、関数はテンプレート パラメータとして整数のリストを受け取り、これらのインデックスの値のみを持つタプルを返します。

たとえば、 タプル があるとします。tuple<int,String,char,float> tを呼び出すとproject<1,3>(t)タイプ のタプルになりtuple<String,float>ます。

もちろん、キーは再帰的なテンプレートのようです。しかし、私はそれを機能させることができません。射影演算の戻り値の型を計算する構造体を宣言することから始めてみました。それでも失敗します。これが私が試したものです:

template<typename T, size_t... indexes>
class Projection{
};

// Specialization for no index => Empty tuple
template<>
template<typename... T>
class Projection<std::tuple<T...>>{
   typedef std::tuple<T...> InputTuple;
   typedef std::tuple<> Tuple;
};

// Specialization for one or more parameters
template<size_t Index1, size_t... others>
template<typename... T>
class Projection<std::tuple<T...>,Index1,others...>{
    typedef std::tuple<T...> InputTuple;

    // The type of a projection with one column less
    typedef Projection<std::tuple<T...>,others...> TupleMinusOne;

    // The result type is the catenation of TupleMinusOne plus the column projected in this     step
    typedef decltype(std::tuple_cat(std::make_tuple(std::get<Index1>(InputTuple())),typename TupleMinusOne::Tuple())) Tuple;
};

これはコンパイルされます。空のタプルを使用した基本ケースも機能します。つまり、次のようになります。

Projection<std::tuple<int,std::string>>::Tuple t;

t空のタプルになります。ただし、再帰ケースはコンパイルされません。

Projection<std::tuple<int,std::string>,1>::Tuple t;

次のエラーが表示されます。

Test.cpp:79:1: error: ‘Tuple’ is not a member of ‘Projection<std::tuple<int, float>, 1ul>’

再帰ケースが認識されないようですが、なぜですか?

4

2 に答える 2

3

再帰的なテンプレートが必要になることはほとんどありません。通常、パック展開はより明確で単純です。この場合、次を使用しますtuple_element

template<typename T, size_t... indexes>
class Projection{
public:
    using Tuple = std::tuple<typename std::tuple_element<indexes, T>::type...>;
};

同様にproject:

template<size_t... indexes, typename T>
auto project(const T &t) -> typename Projection<T, indexes...>::Tuple {
    return typename Projection<T, indexes...>::Tuple(std::get<indexes>(t)...);
}
于 2014-05-12T15:12:21.970 に答える
1

以下を使用できます。

#define Return(ret) decltype(ret) { return ret; }

template<std::size_t... Is, typename T>
auto project(const T& t) -> Return(std::make_tuple(std::get<Is>(t)...))
于 2014-05-12T15:22:29.440 に答える