Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default values in templates with template arguments ( C++ )

Tags:

c++

templates

Assume I have a template (called ExampleTemplate) that takes two arguments: a container type (e.g. list, vector) and a contained type (e.g. float, bool, etc). Since containers are in fact templates, this template has a template param. This is what I had to write:

#include <vector> #include <list>  using namespace std;  template < template <class,class> class C, typename T> class ExampleTemplate {     C<T,allocator<T> > items; public:     .... };  main() {     ExampleTemplate<list,int> a;     ExampleTemplate<vector,float> b; } 

You may ask what is the "allocator" thing about. Well, Initially, I tried the obvious thing...

template < template <class> class C, typename T> class ExampleTemplate {     C<T> items; }; 

...but I unfortunately found out that the default argument of the allocator...

   vector<T, Alloc>    list<T, Alloc>    etc 

...had to be explicitely "reserved" in the template declaration. This, as you can see, makes the code uglier, and forces me to reproduce the default values of the template arguments (in this case, the allocator).

Which is BAD.

EDIT: The question is not about the specific problem of containers - it is about "Default values in templates with template arguments", and the above is just an example. Answers depending on the knowledge that STL containers have a "::value_type" are not what I am after. Think of the generic problem: if I need to use a template argument C in a template ExampleTemplate, then in the body of ExampleTemplate, do I have to reproduce the default arguments of C when I use it? If I have to, doesn't that introduce unnecessary repetition and other problems (in this case, where C is an STL container, portability issues - e.g. "allocator" )?

like image 960
ttsiodras Avatar asked Mar 14 '11 16:03

ttsiodras


People also ask

Can we specify default value for template arguments?

You cannot give default arguments to the same template parameters in different declarations in the same scope. The compiler will not allow the following example: template<class T = char> class X; template<class T = char> class X { };

CAN default arguments be used with the template class?

Can default arguments be used with the template class? Explanation: The template class can use default arguments.

Can a template be a template parameter?

A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)

Can there be more than one arguments to templates?

Can there be more than one argument to templates? Yes, like normal parameters, we can pass more than one data type as arguments to templates.


1 Answers

Perhaps you'd prefer this:

#include <vector> #include <list>  using namespace std;  template <class Container> class ForExamplePurposes {     typedef typename Container::value_type T;     Container items; public: };  int main() {     ForExamplePurposes< list<int> > a;     ForExamplePurposes< vector<float> > b; } 

This uses "static duck typing". It is also a bit more flexible as it doesn't force the Container type to support STL's Allocator concept.


Perhaps using the type traits idiom can give you a way out:

#include <vector> #include <list>  using namespace std;  struct MyFunkyContainer {     typedef int funky_type;     // ... rest of custom container declaration };  // General case assumes STL-compatible container template <class Container> struct ValueTypeOf {     typedef typename Container::value_type type; };  // Specialization for MyFunkyContainer template <> struct ValueTypeOf<MyFunkyContainer> {     typedef MyFunkyContainer::funky_type type; };   template <class Container> class ForExamplePurposes {     typedef typename ValueTypeOf<Container>::type T;     Container items; public: };  int main() {     ForExamplePurposes< list<int> > a;     ForExamplePurposes< vector<float> > b;     ForExamplePurposes< MyFunkyContainer > c; } 

Someone who wants to use ForExamplePurposes with a non-STL-compliant container would need to specialize the ValueTypeOf traits class.

like image 120
Emile Cormier Avatar answered Sep 22 '22 13:09

Emile Cormier