将类声明转发为模板参数。为什么这样做?

时间:2016-09-01 19:07:55

标签: c++

我一直在玩一些c ++模板元编程,我发现了一些我认为相当特殊的情况。 假设我有以下课程。

template<typename T>
class Foo{
};

后来我发现我使用了一个类的foward声明(我假设它被视为它被视为),因为模板参数是这样的

Foo<class bar> bar1;

我还发现以下内容也编译得很好。

Foo<class bar()> bar2;
Foo<class bar(int a)> bar3;

所以我的问题是,为什么这样做。这三种情况都发生了什么 根据标准,我不能在此时声明一个类,所以这会失败:

Foo<class bar{}> bar4

我最初的假设是这只是一个前向声明,你实际上可以在该指针处声明一个类(我可以看到它的可能用途)。 但是,你做不到。所以我的第二个问题是上面有什么用?是否有任何实际用途,或者仅仅是c ++如何工作的结果,这是合法的。我可以看到的一个用途是您可以使用它来创建类型的标记信息。

我使用的是最新版本的g ++

2 个答案:

答案 0 :(得分:6)

在所有3个案例中,您都在向前声明类bar,因此您必须在以后定义它。

Foo<class bar> bar1;

这是有效的,因为它允许在模板参数中第一次声明一个类,即它等同于

class bar;
Foo<bar> bar1;
Foo<class bar()> bar2;

这将创建类bar,就像之前一样,并创建一个不带参数的函数并返回bar

Foo<class bar(int a)> bar3;

这与第二个类似,只是在这里,它声明了一个函数采用int,而不是没有。它相当于

class bar;
Foo<bar(int)> bar3;

答案 1 :(得分:0)

语言需要Foo< ... >中的类型。你提供的是一种不完整的类型&#34; (bar尚未定义),但这很好,因为T实际上并未在模板中的任何位置使用过。

C ++允许语法class bar引用类bar以与C兼容,您必须说struct bar来引用定义为struct bar { ... };的类型。在C ++中,如果编译器已经知道struct是一个类,则class / bar关键字是可选的。

class bar()class bar(int a)是函数类型。它们分别表示bar ()bar (int),即函数(不带参数/取int)返回bar