我一直在玩一些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 ++
答案 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
。