C ++允许在一个名称空间中使用具有相同名称的类和函数:
struct S {};
void S() {}
在这种情况下,纯名称S
表示函数S
。要改为使用struct,您需要在name之前显式添加struct
。
它也可以制作功能模板并仍然使用它们:
template <class T>
void S() {}
struct S {};
但禁止使用模板结构
void S() {}
template <class T>
struct S {};
和gives error是这样的:
error: redefinition of 'S' as different kind of symbol
这是什么原因?为什么不允许在这里使用模板结构?是否存在在struct
之前使用显式关键字S
(如非模板版本)无法解决名称冲突的情况?也许存在提案?
答案 0 :(得分:16)
C ++允许在一个名称空间中使用具有相同名称的类和函数。
struct S {}; void S() {}
通常,当您声明struct S
时,您可以通过两种方式引用该类型:S
和struct S
。但这只是在你宣布其他名为S
的东西之前,例如,一个函数。执行此操作时,该类型的名称不再是S
。它只是struct S
。名称S
是为函数保留的。
这是为了与C兼容.C代码经常使用此设备。与C ++不同,C将struct和union标记放在与普通标识符不同的名称空间中,而struct S
不能简称为S
。
所以C ++为了能够编译使用这个设备的C代码,对于作为不同类型的标识符重用的struct标记来说是一个例外。
由于class
几乎与struct
同义,因此也会对class
关键字执行此操作。
但是C没有模板,也没有必要为它们提供向后兼容性,因此没有类模板的例外。
答案 1 :(得分:3)
我认为允许函数模板名称与允许重载的其他名称相同,而明确禁止类模板名称根据
匹配其他名称14个模板[temp]
- 除了(14.5.5)中规定的情况外,类模板不得与同一范围(3.3)中的任何其他模板,类,函数,变量,枚举,枚举器,命名空间或类型具有相同的名称。 / LI> 醇>
[更新]这篇文章的其余部分让我觉得功能模板没有导致相同错误的情况违反了标准要求:
除非函数模板可以由具有相同名称的非模板函数(8.3.5)或具有相同名称的其他函数模板(14.8.3)重载,在名称空间中声明的模板名称范围或课堂 范围在该范围内应是唯一的。
和VS / clang / gcc似乎不同意godbolt