STL container as a template parameter

I am trying to pass an STL container as a template parameter. In this case, the vector.

Here is my non-functional code:

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

Is this what I am trying to do at all because the compiler cannot internalize this?

+6
source share
5 answers

There are several errors in the code, here is a working example:

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

The main mistake of your codes is that std::vector takes two template arguments. It looks like template<class T, class Allocator = std::allocator<T>> class vector; . In addition, Joachim Pileborg is right about the double pointer problem, IUnknown** . However, you can simplify the code as follows:

 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 } 
+12
source

Another possibility is to make TContainer variation pattern:

 #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; } 
+7
source

There are three different types of template arguments: values, types, and templates:

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

When using these templates, you need to provide an argument of the correct type:

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

When using the third form, the template template argument, the template passed as the argument must match the template template argument declaration. In my simple examples, pattern E expects an argument to a pattern template that takes a single type argument.

In the code in the question, the first argument in the Foobar declaration is the template <class> class TContainer . In the place where it was used, the passed std::vector template:

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

The problem is that the template template argument says that it must have one argument, but the template that is passed as the actual argument has two or more. Formally std::vector is

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

To use std::vector> as the first argument to Foobar , the definition of Foobar` needs to be changed so that the first argument takes two arguments of the type:

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

To begin with, you are likely to get some compiler errors, so you should add them to the question, since right now we can only guess.

Secondly, I assume this is because of your template:

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

Here you tell the compiler that the template parameter is a pointer, but then you have a constructor:

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

In the constructor, you declare container as a TContainer with TObject* members, but since TObject already a pointer, now you have a pointer to a pointer. If TObject is equal to IUnknown* , then TObject* is equal to IUnknown** . You have the same problem when declaring member variable container_ .

I recommend that you discard the type of pointer when declaring bla :

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

You can create a synonym for your vector type with typedef to simplify coding.

 typedef vector<MyClass> List; 

Then use List as a template parameter as a "normal" type.

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

Source: https://habr.com/ru/post/953151/


All Articles