Templates with implicit parameters, forward declar

2020-07-07 10:35发布

问题:

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

回答1:

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



回答2:

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"


回答3:

You must make sure only the first declaration has the default value of the parameter. This can be accomplished by first defining a forward-declaration-only header, then including it from both List.h and Analysis.h. In the definition in List.h, do not include the default value.



回答4:

you may define the default parameter in only one place (for a given translation). it's most useful to do so at the class declaration, and a bad idea to define it at the forward.

a forward does not need the default parameter (you'll just have to type it in some cases).

you could create another simple template type which implements this in conjunction with a forward, if you really want a default parameter. then you access the result via a typedef. you can do this using a forward of List.



回答5:

You must include List.h in every file, where you are using it. Declaration is enought only for nontemplate types. For template types you must include header file for every compilation unit.