3

我试图T从 type 推断出基础模板类型E = T<T2,T3>。例如,这可以使模板函数 pair_maker(const E & a) 可以与几种类似类型的容器之一一起使用。粗略的元代码:

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>

会将类型vector<int>转换为vector<pair(int,std::string)>或。whatever<T1>whatever<pair(T1,std::string)>

类型剖析的另一个类似示例是 std::array (或类似容器),我想找出容器类型以创建一个新的类似数组。例如对于这些类型的功能(这是现在实际的工作代码)

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>{} ;
}

这很好用,但我想要的是自动显式使用“std::array”。

对于 std::array 有 tuple_size 特性会有所帮助,并且可以使用类似的东西来查找type任何第二个参数,但我还是想不出任何东西来查找容器类型。

总结一下:什么样的机器(如果有的话)可以用于这样的情况。在何种程度上可以处理模板参数、模板-模板参数、任意数量的参数和未知类型的非模板参数的混合。

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 的解决方案几乎相同,但对我来说,使用语法更美观,将模板参数放在::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...> ;

请注意,在模板上下文中使用 this 时,在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;
}

这样做是获取一个类型的对象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 回答