帮助 c++ 模板 模板

发布于 2024-07-24 06:13:49 字数 1371 浏览 4 评论 0原文

好的,所以我写了一个类似 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);
}

没有模板 typedef,所以我创建了一个特征类来保存类型 输出迭代器来自:

template <typename ObjA, typename ObjB, template <typename> class Container>
struct cartesian_product_traits
{
    typedef Container<std::pair<ObjA, ObjB> > type;
};

那么我可以说:

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);

但这似乎无法编译。 我收到一个很好的错误:

error C3201: the template parameter list for class template 'std::vector' does not match the template parameter list for template parameter 'Container'

所以我很困惑。 我该如何让它发挥作用?

Ok, so I wrote an stl-like algorithm called cartesian_product. For those who don't know, the cartesian product is every possible pair of elements from two sets. So the cartesian product of {1, 2, 3} and {10, 20, 30} is

{(1,10), (1,20), (1,30), (2,10), (2,20), (2,30), (3,10), (3,20), (3,30)}

So the function looks like

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

There aren't template typedefs, so I made a traits class to hold the type that
the output iterator is from:

template <typename ObjA, typename ObjB, template <typename> class Container>
struct cartesian_product_traits
{
    typedef Container<std::pair<ObjA, ObjB> > type;
};

So then I can say:

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);

but this doesn't seem to compile. I get a nice error:

error C3201: the template parameter list for class template 'std::vector' does not match the template parameter list for template parameter 'Container'

So I'm stumped. How do I get this to work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

窗影残 2024-07-31 06:13:49

矢量的模板参数列表不仅仅是一个元素,它需要两个:

template < class T, class Allocator = allocator<T> > class vector

因此为了接受矢量,您需要有一个带有两个空格的模板模板参数:

template <typename ObjA, typename ObjB, template <typename, typename> class Container>
struct cartesian_product_traits

已编辑:删除一些建议,误读你的代码。

正确执行此操作的方法是在模板模板参数上使用可变参数宏:

template <typename ObjA, typename ObjB, template <typename ...> class Container>
struct cartesian_product_traits

但这距离成为标准还很远。 如果这是我的代码,我可能会让消费者敲出完整的模板:

std::vector< std::pair<int, int> >

比 短

cartesian_product_traits<int, int, vector>

,后者只有在笛卡尔积的定义发生变化时才有帮助。

The template parameter list for vector isn't just one element, it takes two:

template < class T, class Allocator = allocator<T> > class vector

so in order to accept vector, you need to have a template template parameter with two blanks:

template <typename ObjA, typename ObjB, template <typename, typename> class Container>
struct cartesian_product_traits

Edited: cut some advice, misread your code.

The way to do this properly would be to use a variadic macro on the template template parameter:

template <typename ObjA, typename ObjB, template <typename ...> class Container>
struct cartesian_product_traits

But that's far away from being a standard. If it were my code, I'd probably just have the consumers pound out the full template:

std::vector< std::pair<int, int> >

is shorter than

cartesian_product_traits<int, int, vector>

and the latter would only help if the definition for a Cartesian product changed.

—━☆沉默づ 2024-07-31 06:13:49

std::vector 的模板实际上非常复杂(带有分配器和 c 的可选模板参数)——并且 stdlib 中的其他容器也没有更简单。 站在你的立场上,我会将cartesian_product_traits的第三个参数设置为一个简单的typename PairsContainer,并依赖调用者解决将其作为合适的容器传递的小麻烦对。

std::vector's template is actually quite complex (with optional template parameters for allocators &c) -- and other containers in the stdlib aren't any simpler either. In your shoes, I'd make the third parameter of cartesian_product_traits into a plain typename PairsContainer and depend on the caller to go to the small trouble of passing it as a suitable container of pairs.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文