3

I'm trying to deduce the underlying template type T from a type E = T<T2,T3>. This would for example make it possible to make a template function pair_maker(const E & a) which can be used with one of several similar types of containers. Rough meta code:

template <typename T>
auto pairmaker(const E & a) -> PairContents<E,std::string>::type {
    ContainerPairMaker<E,std::string>::type output;
    ... some code ...
    return output;
}

PairContents<E,std::string>

would transform the type vector<int> into vector<pair(int,std::string)> or whatever<T1> into whatever<pair(T1,std::string)>.

Another similar example of type dissection is for std::array (or similar containers) where I like to figure out the container type to make a new similar array. For example for these kind of functions (this is actual working code now)

template <typename T > 
auto make_some3(const T & a) 
           -> std::array<typename T::value_type,10*std::tuple_size<T>::value>{   
   return std::array<typename T::value_type,10*std::tuple_size<T>::value>{} ;
}

This works fine but what I'm after is to make the explicit use of 'std::array' automatic.

For std::array there's the tuple_size trait which helps, and a similar thing can be used to find the type for any second argument, but again I can't think of anything for finding the container type.

To summarize: what kind of machinery (if any) can be used for cases like these. To which extent is it possible to deal with mixes of template arguments, template-template arguments, any number of arguments, and non-template arguments of unknown types.

4

3 に答える 3

13

ここにアイデアがあります:

 template <typename T, typename ...>
 struct tmpl_rebind
 {
     typedef T type;
 };

 template <template <typename ...> class Tmpl, typename ...T, typename ...Args>
 struct tmpl_rebind<Tmpl<T...>, Args...>
 {
     typedef Tmpl<Args...> type;
 };

使用法:

typedef std::vector<int> IV;
typedef typename tmpl_rebind<IV, std::pair<double, std::string>>::type PV;

PV = std::vector<std::pair<double, std::string>>

于 2012-07-30T14:45:55.517 に答える
4

これは、Kerrek SB からの回答の変形として思いついた自己回答です。

トレイトから抽出std::vectorstd::vector<int>て公開するトレイトを作成することができ::typeます。はい、このソリューションは Kerrek のソリューションとほぼ同じですが、私にとって use 構文はより美しく、テンプレート パラメータを の後に置きます::type

template <typename T, typename ...>
struct retemplate
{
    typedef T type;
};

template <template <typename ...> class Tmpl, typename ...T>
struct retemplate<Tmpl<T...>>
{
   template <typename ...AR>
   using type=Tmpl<AR...> ;
};

これにより、実際にretemplate<T<A,B,C>>::typeはテンプレートと等しくなりますT

使用例:

typedef std::vector<int> intvec; 
typedef retemplate<intvec>::type<double> doublevec; 

またはコンテナタイプを公開する

typedef std::vector<int> intv;
template <typename ...T>
using vector_T= retemplate<intv>::type<T...> ;

これをテンプレート コンテキストで使用する場合は、次のように のtemplate直後に追加が必要であることに注意してください::: (Xeo からのコメントについて詳述)

template <typename T>
typename retemplate<T>::template type<double> containedDouble(T& a) {
   decltype(containedDouble(a)) out;
   for (auto &i : a)
      out.push_back(i);
   return out;
}

それが行うことは、 type のオブジェクトを取得し、T1<T2>その内容を にコピーすることT1<double>です。たとえば、T1==std::vectorT2==int.

于 2012-07-30T21:52:42.823 に答える
2

A. Alexandrescuの著書Modern C++ Designを参照することをお勧めします。

私の記憶が正しければ、彼は型リストを使用して任意の型をリストのような方法で格納およびアクセスする方法を説明しています。これらのリストは、さまざまな状況で型情報を提供するために使用できます。Lokiの実装を見て、型リストがどのように利用できるかを確認してください。

これがまったく役立つかどうかはわかりませんが、目前の特定の問題を解決するか、少なくともよりよく理解するために、Loki で使用されているアイデアから何かを学ぶことができるかもしれません.

于 2012-07-30T15:44:32.027 に答える