8

有一个带有隐式参数的模板类声明:

列表.h

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

我尝试在不同的头文件中使用流动的前向声明:

分析.h

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

但 G++ 显示此错误:

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

如果我使用没有隐式参数的前向声明

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

编译器不接受这种结构

分析.h

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

并显示以下错误(即不接受隐式值):

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

更新的问题:

我从模板定义中删除了默认参数:

列表.h

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

使用类 List 的第一个文件具有参数属性的隐式值的前向声明

分析1.h

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

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

第二类使用类 List WITH 前向定义使用隐式值

分析2.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
};

第二类使用类 List WITHOUT 前向定义使用隐式值

分析2.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)
};
4

5 回答 5

5

简单的。从定义中删除默认值,因为您已经在前向声明中提到了这一点。

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

写:

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

在线演示:http ://www.ideone.com/oj0jK

于 2011-02-05T09:43:45.587 回答
2

一种可能的解决方案是声明另一个头文件 List_fwd.h

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

因此,在 List.h 和 Analysis.h 中,您在开头都包含 List_fwd.h。所以 List.h 变成

#include "List_fwd.h"

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

和分析.h

#include "List_fwd.h"
于 2011-02-05T10:45:48.010 回答
1

您必须确保只有第一个声明具有参数的默认值。这可以通过首先定义一个仅前向声明的标头,然后从两者中包含它来List.h实现Analysis.h。在 中的定义中List.h,不包括默认值。

于 2011-02-05T09:43:54.347 回答
0

您可以只在一个地方定义默认参数(对于给定的翻译)。在类声明中这样做是最有用的,而在前面定义它是一个坏主意。

forward 不需要默认参数(在某些情况下您只需键入它)。

如果你真的想要一个默认参数,你可以创建另一个简单的模板类型,它与转发一起实现这一点。然后您通过 typedef 访问结果。您可以使用 List 的转发来执行此操作。

于 2011-02-05T09:43:43.437 回答
0

您必须List.h 在使用它的每个文件中包含它。声明仅适用于非模板类型。对于模板类型,您必须包含每个编译单元的头文件。

于 2011-02-05T10:05:43.790 回答