19

に戻すためにaを取り除く方法はありますか?std::tuple<T...>T...

vct<T...>が既存 可変個引数クラス テンプレートであるとします。

using U = std::tuple<int,char,std::string>;
using X = vct<int,char,std::string>;
using Y = vct< strip<U> >;            // should be same as X

ノート

std::tuple_elementについては知っていますが、次のように使用できる形式ですべての要素が必要ですT...

参考までに、私はこの質問を見つけましたが、これは似ていますが、私のニーズはやや単純です (したがって、より単純な解決策があることを願っています): 必要なのは、にある型のリストだけですtupletupleインスタンスの実際の値。

4

5 に答える 5

22
template<typename>
struct strip;

template<typename ...T>
struct strip<std::tuple<T...>>
{
   using type = vct<T...>;
};

次に、これを次のように使用します。

using Y = strip<U>::type;

Yはと同じXです。

于 2013-03-14T19:53:17.757 に答える
14

いいえ、これは不可能です。引数パックは型推論の結果であり、他のコンテキストでは生成できません。

この方法で求めているものと同様のことを行うことができます。

template<template<typename...> class T, typename>
struct instantiate_with_arg_pack { };

template<template<typename...> class T, typename... Ts>
struct instantiate_with_arg_pack<T, std::tuple<Ts...>>
{
    using type = T<Ts...>;
};

template<typename... Ts>
struct vct { };

int main()
{
    using U = std::tuple<int,char,std::string>;
    using X = vct<int,char,std::string>;
    using Y = instantiate_with_arg_pack<vct, U>::type;
}

実際には、引数パックをタプルに保持する必要はありません: 任意の可変個引数クラス テンプレートは問題ありません:

template<template<typename...> class T, typename>
struct instantiate_with_arg_pack { };

template<
    template<typename...> class T, 
    template<typename...> class U, // <===
    typename... Ts
    >
struct instantiate_with_arg_pack<T, U<Ts...>>
//                                   ^^^^^^^^
{
    using type = T<Ts...>;
};

template<typename... Ts>
struct vct { };

int main()
{
    using U = std::tuple<int,char,std::string>;
    using X = vct<int,char,std::string>;
    using Y = instantiate_with_arg_pack<vct, X>::type;
    //                                        ^

    // Won't fire
    static_assert(
        std::is_same<Y, vct<int,char,std::string>>::value, 
        "Error!");
}

そして、これがライブの例です。

于 2013-03-14T19:53:34.160 に答える
4

パラメータパックを直接「返す」ことはできないため、必要なのは次のようなものです。

template< typename... Ts >
struct vct
{ ... };

template< typename T >
struct make_vct;

template< typename... Ts >
struct make_vct< std::tuple< Ts... > >
{
    typedef vct< Ts... > type;
};

と使用

using Y = make_vct< U >::type;
于 2013-03-14T19:52:47.590 に答える
3

ここでの目標は、パラメーター パックをテンプレートのインスタンスから別のテンプレートにコピーできるようにすることです。に制限しませんでしtupleた。なぜに制限するのtupleですか?

template<template<typename...>class Target, typename Src>
struct copy_pack_types;

template<template<typename...>class Target, template<typename...>class Src, typename... Ts>
struct copy_pack_types< Target, Src<Ts...> > {
  typedef Target<Ts...> type;
};

template<template<typename... Ts>class Target, typename Src>
using CopyPackTypes = typename copy_pack_types<Target, Src>::type;

#include <string>
#include <tuple>
template<typename... Ts> struct vct;
template<typename... Ts> struct vct2;
using U = std::tuple<int,char,std::string>;
using X = vct<int,char,std::string>;
using Y = CopyPackTypes< vct, U >;            // should be same as X
using Z = CopyPackTypes< vct2, U >;            // should be different from X

#include <iostream>
#include <type_traits>
int main() {
  std::cout << std::is_same< X, Y >::value << "\n";
  std::cout << std::is_same< Z, Y >::value << "\n";
  std::cout << std::is_same< Z, vct2<int,char,std::string> >::value << "\n";
}

出力は期待どおり「1 0 1」です。

CopyPackTypes、ターゲット テンプレートと、パラメータ パックから構築されたソース タイプを唯一の引数として取ります。次に、パラメーター パックをターゲット テンプレートにコピーします。

パラメーター パックを持ち運ぶ標準的な手法の 1 つは、次のような使用しない型を作成することです。

template<typename...>
struct types {};

タイプのリストのプレースホルダーとしてのみ存在します。次に、これらのいくつかを別のテンプレートに渡すことができます。各パックは互いに「踏む」ことはありません。対象のテンプレートに適用する必要がある場合は、上記の「CopyPackTypes」のようなものを使用して適用します。

インデックスのパックにも同様の手法が使用されます。

template<size_t...>
struct seq {};

それ以外の場合は、パラメーターの塊を持ち運ぶための「黒いスレート」である役に立たない型です。

于 2013-03-14T20:34:41.137 に答える