Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Templates with implicit parameters, forward declaration, C++

There is a declaration of template class with implicit parameters:

List.h

template <typename Item, const bool attribute = true>
class List: public OList <item, attribute>
{
    public:
    List() : OList<Item, attribute> () {}
    ....
};

I tried to use the fllowing forward declaration in a different header file:

Analysis.h

template <typename T, const bool attribute = true>
class List;

But G++ shows this error:

List.h:28: error: redefinition of default argument for `bool attribute'
Analysis.h:43: error:   original definition appeared here

If I use the forward declaration without implicit parameters

template <typename T, const bool attribute>
class List;

compiler does not accept this construction

Analysis.h

void function (List <Object> *list)
{
}

and shows the following error (i.e. does not accept the implicit value):

Analysis.h:55: error: wrong number of template arguments (1, should be 2)
Analysis.h:44: error: provided for `template<class T, bool destructable> struct List'
Analysis.h:55: error: ISO C++ forbids declaration of `list' with no type

Updated question:

I removed the default parameter from the template definition:

List.h

template <typename Item, const bool attribute>
class List: public OList <item, attribute>
{
    public:
    List() : OList<Item, attribute> () {}
    ....
};

The first file using class List has forward declaration with implicit value of the parameter attribute

Analysis1.h

template <typename T, const bool attribute = true>
class List;  //OK

class Analysis1
{
    void function(List <Object> *list); //OK
};

The second class using class List WITH forward definition using the implicit value

Analysis2.h

template <typename T, const bool attribute = true> // Redefinition of default argument for `bool attribute'
class List; 

class Analysis2
{
    void function(List <Object> *list); //OK
};

The second class using class List WITHOUT forward definition using the implicit value

Analysis2.h

template <typename T, const bool attribute> // OK
class List; 

class Analysis2
{
    void function(List <Object> *list); //Wrong number of template arguments (1, should be 2)
};
like image 691
Robo Avatar asked Feb 05 '11 09:02

Robo


People also ask

Can you forward declare templates?

You can declare default arguments for a template only for the first declaration of the template. If you want allow users to forward declare a class template, you should provide a forwarding header. If you want to forward declare someone else's class template using defaults, you are out of luck! Save this answer.

Can template parameters have default values?

Template parameters may have default arguments. The set of default template arguments accumulates over all declarations of a given template.

Why should I use forward declarations?

A forward declaration allows us to tell the compiler about the existence of an identifier before actually defining the identifier. In the case of functions, this allows us to tell the compiler about the existence of a function before we define the function's body.

What is parameterized template?

In UML models, template parameters are formal parameters that once bound to actual values, called template arguments, make templates usable model elements. You can use template parameters to create general definitions of particular types of template.


2 Answers

Simple. Remove the default value from the definition, since you already mentioned that in the forward declaration.

template <typename Item, const bool attribute = true> //<--- remove this 'true`
class List: public OList <item, attribute>
{
  //..
};

Write:

template <typename Item, const bool attribute>  //<--- this is correct!
class List: public OList <item, attribute>
{
  //..
};

Online Demo : http://www.ideone.com/oj0jK

like image 66
Nawaz Avatar answered Oct 06 '22 06:10

Nawaz


A possible solution is to declare an other header file, List_fwd.h

template <typename Item, const bool attribute>
class List;

So in both List.h and Analysis.h you include List_fwd.h at the beginning. So List.h becomes

#include "List_fwd.h"

template <typename Item, const bool attribute = true>
class List: public OList <item, attribute>
{
    public:
    List() : OList<Item, attribute> () {}
    ...
};

And Analysis.h

#include "List_fwd.h"
like image 29
mattia.penati Avatar answered Oct 06 '22 06:10

mattia.penati