rlb*_*ond 2 c++ templates template-templates
好吧,所以我写了一个类似stl的算法cartesian_product
.对于那些不知道的人来说,笛卡尔积是两组中每一对可能的元素.所以笛卡尔乘积{1, 2, 3}
和{10, 20, 30}
是
{(1,10), (1,20), (1,30), (2,10), (2,20), (2,30), (3,10), (3,20), (3,30)}
所以功能看起来像
template <typename InIt1, typename InIt2, typename OutIt>
void
cartesian_product(InIt1 first1, InIt1 last1, InIt2 first2, InIt2 last2, OutIt out)
{
for (; first1 != last1; ++first1)
for (InIt2 it = first2; it != last2; ++it)
*out++ = std::make_pair(*first1, *it);
}
Run Code Online (Sandbox Code Playgroud)
没有模板typedef,所以我创建了一个traits类来保存输出迭代器来自的类型:
template <typename ObjA, typename ObjB, template <typename> class Container>
struct cartesian_product_traits
{
typedef Container<std::pair<ObjA, ObjB> > type;
};
Run Code Online (Sandbox Code Playgroud)
那么我可以说:
typedef cartesian_product_traits<int, int, std::vector>::type IntPairList;
IntPairList my_list;
cartesian_product(v1.begin(), v1.end(),
v2.begin(), v2.end(),
std::back_inserter(my_list);
Run Code Online (Sandbox Code Playgroud)
但这似乎没有编译.我收到一个很好的错误:
error C3201: the template parameter list for class template 'std::vector' does not match the template parameter list for template parameter 'Container'
Run Code Online (Sandbox Code Playgroud)
所以我很难过.我如何让它工作?
vector的模板参数列表不仅仅是一个元素,它需要两个:
template < class T, class Allocator = allocator<T> > class vector
Run Code Online (Sandbox Code Playgroud)
所以为了接受矢量,你需要有一个带有两个空格的模板模板参数:
template <typename ObjA, typename ObjB, template <typename, typename> class Container>
struct cartesian_product_traits
Run Code Online (Sandbox Code Playgroud)
编辑:削减一些建议,误读你的代码.
正确执行此操作的方法是在模板模板参数上使用可变参数宏:
template <typename ObjA, typename ObjB, template <typename ...> class Container>
struct cartesian_product_traits
Run Code Online (Sandbox Code Playgroud)
但这远远不是一个标准.如果是我的代码,我可能只是让消费者敲出完整的模板:
std::vector< std::pair<int, int> >
Run Code Online (Sandbox Code Playgroud)
比...短
cartesian_product_traits<int, int, vector>
Run Code Online (Sandbox Code Playgroud)
而后者只有在笛卡尔积的定义发生变化时才会有所帮助.
归档时间: |
|
查看次数: |
5427 次 |
最近记录: |