我正在尝试从类型T
中推断出基础模板类型E = T<T2,T3>
。这将例如使得可以制作模板函数pair_maker(const E&amp; 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
,但我再也想不出有什么东西可以找到容器类型。
总结:什么样的机器(如果有的话)可以用于这样的情况。在多大程度上可以处理模板参数,模板模板参数,任意数量的参数和未知类型的非模板参数的混合。
答案 0 :(得分:12)
这是一个想法:
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>>
。
答案 1 :(得分:4)
这是我想出的一个自我答案,作为Kerrek SB答案的变体
可以制作从std::vector
中提取std::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...> ;
请注意,在模板上下文中使用此功能时,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::vector
和T2==int
。
答案 2 :(得分:2)
我建议看一下 A. Alexandrescu 的书现代C ++设计。
如果我没记错的话,他解释了如何使用类型列表以类似列表的方式存储和访问任意类型。这些列表可用于在许多不同情况下提供类型信息。查看Loki的实现,了解如何使用类型列表。
我不确定这是否有用,但也许您可以从Loki中使用的想法中学到一些东西,以便解决或至少更好地理解您手头的具体问题。