我可以使用 std::vector 作为模板参数还是需要 std::vector<T>?

Can I use std::vector as a template parameter or does it need to be std::vector<T>?

本文关键字:vector std gt lt 参数 可以使 我可以      更新时间:2023-10-16

我知道这是一个简单的问题,但我就是找不到答案。

我正在尝试做这样的事情,但不是std::vector最终我希望它是std::shared_ptr或std::weak_ptr:

template <int dim, class ChunkClass, class PtrClass>
class BaseChunkWindow : public IChunkWindow<BaseChunkWindow<dim, ChunkClass, PtrClass>, IChunk<ChunkClass>> {
public:
...
private:
PtrClass< IChunk<ChunkClass> > ptr;  <-- compiler doesn't like this line, however IChunk<ChunkClass>* works
};

这取决于你要传递给什么,如果你要实例化的模板接受一个接受2(或c++11中可变数量)类型的类模板作为参数,那么你可以将std::vector传递给它。然而,在大多数情况下,模板需要类型作为参数,并且不能传递类模板std::vector。

    template <class T>
    struct gimme_a_type{};
    template <template <class,class> class T>
    struct gimme_a_template{};
    gimme_a_type<std::vector> //<-- does not compile, expected a type, got a template
    gimme_a_type<std::vector<int> > //<-- compiles, expected a type, got a type
    gimme_a_template<std::vector> //<-- compiles, expected a template, got a template that has the correct signature
    gimme_a_template<std::vector<int> > //<-- does not compile, expected a template, got a type

回应你的编辑,使用类模板作为模板参数有困难。当您在试图传递的类模板中具有默认实参(在我们的示例中为std::vector)时,准确匹配形参的数量实际上很难做到。注意,上面的例子需要一个类模板,它接受两个类型,而不是一个。这是因为std::vector有两个参数,第二个参数默认为std::allocator<T>

下面的例子演示了这个问题:

    template <template <class, class> class Tem>
    struct A
    {
        Tem<int> v; //<-- fails to compile on gcc, Tem takes two parameters
        Tem<int, std::allocator<int> >; //<-- compiles, but requires a priori knowledge of Tem
    };
    template <template <class...> class Tem>
    struct A2
    {
      Tem<int> v; //<-- This C++11 example will work, but still isn't perfect.
    };

c++ 11的例子更好,但是如果有人传递了一个作为template <class, bool = false> class A3签名的类,它又失败了,因为A2需要一个接受类型的类模板,而不是类型和非类型的混合(false是这个例子中的非类型模板参数)。所以即使A3<int>是一个有效的实例化,你也不能把这个类传递给A2。解决方案是始终在模板参数列表中使用类型,并使用std::integral_constant包装器模板传递整型常量。

有两种方法。

有限制的方法是使用模板模板形参,只传递有限数量的形参,例如3.

template<template<class,class,class> class Cont, class T, class V, class U>
void f(Cont<T,V,U>&& cont) {
    //...
}

然而,这是相当有限的,如果你决定在将来改变它,可能很难管理。

所以你可以用c++ 11中新的可变模板来做:

template<template<class...> class Cont, typename F, typename... Rest>
void f(Cont<F, Rest...>&& cont) {
    //...
}

这将适用于其他容器或东西,并且可能更容易管理。

相关文章: