我正在尝试将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;
}
这是我正在尝试做的事情,因为编译器不能吞下这个吗?
答案 0 :(得分:14)
您的代码有几个问题,这是一个有效的例子:
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;
。此外,Joachim Pileborg关于双指针问题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
}
答案 1 :(得分:9)
另一种可能性是使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;
}
答案 2 :(得分:8)
有三种不同的模板参数:值,类型和模板:
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 { ... };
答案 3 :(得分:0)
首先,您可能会遇到一些编译器错误,如果是这样,您应该将它们添加到问题中,因为我们现在只能猜测。
其次,由于您的模板参数,我猜测是
Foobar<std::vector, IUnknown*> bla( v );
// ^^^^^^^^^
在这里,您告诉编译器模板参数是一个指针,但是您有构造函数:
Foobar( TContainer<TObject*> & container )
// ^^^^^^^^
在构造函数中,您将container
声明为TContainer
成员TObject*
,但由于TObject
已经是指针,因此您现在有一个指针指向终场。如果TObject
等于IUnknown*
,则TObject*
等于IUnknown**
。声明container_
成员变量时会遇到同样的问题。
我建议您在声明bla
:
Foobar<std::vector, IUnknown> bla( v );
// ^^^^^^^^
答案 4 :(得分:0)
您可以使用typedef创建矢量类型的同义词,以简化编码。
typedef vector<MyClass> List;
然后使用List作为模板参数作为“普通”类型。
template<class T, class K>
class Foobar {...}
Foobar<List> variable;