STL容器作为模板参数

STL container as a template parameter

本文关键字:参数 STL      更新时间:2023-10-16

我正试图传递一个STL容器作为模板参数。在这种情况下,向量。

这是我的非功能代码:

template<template<class> class TContainer, class TObject>
class Foobar
{
public:
    explicit Foobar( TContainer<TObject*> & container )
    :
    container_( container ){}

private:
    TContainer<TObject*> & container_;
};

int _tmain(int argc, _TCHAR* argv[])
{
    std::vector<IUnknown*> v;
    Foobar<std::vector, IUnknown*> bla( v );
    return 0;
}

这是我试图做的事情吗,因为编译器无法接受这一点?

您的代码有几个问题,下面是一个工作示例:

template<template<class, class> class TContainer, class TObject>
class Foobar
{
public:
    explicit Foobar( TContainer<TObject*, std::allocator<TObject*>> & container )
    :
    container_( container ){}
private:
    TContainer<TObject*, std::allocator<TObject*>> & container_;
};
int main()
{
    std::vector<IUnknown*> v;
    Foobar<std::vector, IUnknown> bla( v );
}

代码的主要错误是std::vector采用了两个模板参数。它看起来像这个template<class T, class Allocator = std::allocator<T>> class vector;。此外,约阿希姆·皮莱堡在双指针问题上是对的,IUnknown**。但是,您可以通过以下操作简化代码:

template<class TContainer>
class Foobar
{
public:
    explicit Foobar( TContainer & container )
    :
    container_( container ){}
private:
    TContainer & container_; // Be careful with reference members
};
int main()
{
    std::vector<IUnknown*> v;
    Foobar<std::vector<IUnknown*>> bla( v ); // C++11 decltype(v) could be used
}

另一种可能性是使TContainer成为可变模板:

#include <vector>
struct TObject {};
struct IUnknown {};
template<template<class...> class TContainer, class TObject>
class Foobar
{
public:
    explicit Foobar( TContainer<TObject*> & container ) : container_( container ){}
private:
    TContainer<TObject*> & container_;
};
int main() {
    std::vector<IUnknown*> v;
    Foobar<std::vector, IUnknown> bla( v );
    return 0;
}

有三种不同类型的模板参数:值、类型和模板:

template <int value_argument> class C { };
template <class type_argument> class D { };
template <template<classT> class template_argument> class E { };

当你使用这些模板时,你必须提供一个正确的论点:

C<3> c;
D<int> d;
E<C> e;

当您使用第三种形式(模板模板参数)时,作为参数传递的模板必须与模板模板参数的声明相匹配。在我的简单示例中,模板E需要一个采用一个类型参数的模板模板参数。

在问题中的代码中,Foobar声明中的第一个参数是template <class> class TContainer。在使用时,传递的模板是std::vector:

Foobar<std::vector, IUnknown*> bla(v);

问题是,模板-模板参数说它应该有一个参数,但作为实际参数传递的模板有两个或多个。从形式上讲,std::vector

template <class T, class Allocator = std::allocator<T>> class vector { ... };

为了使用std::vector> as the first argument to Foobar , the definition of Foobar"需要更改,以便第一个参数采用两个类型参数:

template <template<class, class> TContainer, class TObject> class Foobar { ... };

您可以使用typedef创建向量类型的同义词,以简化编码。

typedef vector<MyClass> List;

然后使用List作为"普通"类型的模板参数。

template<class T, class K>
class Foobar {...}
Foobar<List> variable;

首先,您可能会遇到一些编译器错误,如果是这样的话,您应该将它们添加到问题中,因为现在我们只能猜测。

其次,我猜这是因为你的模板参数:

Foobar<std::vector, IUnknown*> bla( v );
//                  ^^^^^^^^^

在这里,你告诉编译器模板参数是一个指针,但你有一个构造函数:

Foobar( TContainer<TObject*> & container )
//                 ^^^^^^^^

在构造函数中,您将container声明为具有TObject*成员的TContainer,但由于TObject已经是一个指针,您现在有一个指向指针的指针。如果TObject等于IUnknown*,则TObject*等于IUnknown**。在声明container_成员变量时也会遇到同样的问题。

我建议您在声明bla:时删除指针类型

Foobar<std::vector, IUnknown> bla( v );
//                  ^^^^^^^^