8

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)
};
Robo
  • 311
  • 5
  • 10
  • Alright I understand your problem. It's because you add the forward declaration in every file where you *use* `List`. DONT DO THAT. Instead add the forward declaration in `List.h` where you *define* the `List` **and** `#include "List.h"` in every file where you use `List`. Let me know if you still face problem! – Nawaz Feb 05 '11 at 11:32
  • so what is your question after update? – UmmaGumma Feb 05 '11 at 11:42

5 Answers5

5

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

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • @Robo: If it worked, then "accept" this answer by clicking on tick mark. So far you didn't accept even a single answer! – Nawaz Feb 05 '11 at 10:03
  • @Nawaz: I'd rather place the default value in the declaration instead of the forward declaration. I think it's even clearer this way. – jopasserat Feb 05 '11 at 10:08
  • If there are more classes using template class List with the deafult parameter attribute in my program, it ic neccessary to add default value of the parameter into each forward declaration? – Robo Feb 05 '11 at 10:36
  • @Robo: It's disappointing and discouraging that you don't accept answers. You didn't accept even a single answer. Why do you think people would care answering your questions when you don't accept it? – Nawaz Feb 05 '11 at 10:41
  • I accepted your answer and thanks for your time... But this model does not work for more then one classes having default parameters of the template... – Robo Feb 05 '11 at 10:46
  • @Robo: Your question is not clear enough. Can you post some code in your post so that I can see what exactly you're trying to say? – Nawaz Feb 05 '11 at 10:49
  • @Robo: Alright I understand your problem. It's because you add the forward declaration in every file where you *use* `List`. DONT DO THAT. Instead add the forward declaration in `List.h` where you *define* the `List` **and** `#include "List.h"` in every file where you use `List`. Let me know if you still face problem! – Nawaz Feb 05 '11 at 11:28
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"
mattia.penati
  • 532
  • 5
  • 18
1

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.

bdonlan
  • 224,562
  • 31
  • 268
  • 324
0

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.

justin
  • 104,054
  • 14
  • 179
  • 226
0

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.

UmmaGumma
  • 5,633
  • 1
  • 31
  • 45
  • But how to avoid the circular delendency in header files using this model? – Robo Feb 05 '11 at 10:50
  • @Robo I don't say, that you can't declare it, I say, that you must include header file. To resolve dependencies you probable must declare classes before including header. But you steal need to include header – UmmaGumma Feb 05 '11 at 11:23
  • @Robo By the way no need to declare it before include :) – UmmaGumma Feb 05 '11 at 11:44