c++ - 为什么 C struct hack 不适用于 C++ 模板声明?

标签 c++ templates struct language-lawyer name-lookup

C 有一个有趣的技巧,其中一个名称可用于声明类型和函数:

struct foo {};
void foo(void);

现在,任何时候我写 foo ,编译器假定我的意思是函数,除非我在它前面加上 struct :
foo();  // call void foo(void)
struct foo bar;  // declare variable of type struct foo

即使使用命名空间和嵌套,这在 C++ 中也能很好地工作!
但它不适用于模板:
template <typename> void bar(void);
template <typename> struct bar {};
// error: conflicting declaration of template struct bar
// previous declaration: template void bar()

为什么?

我们已经开始处理依赖上下文中的消歧器:
typename foo<A>::b();
foo<A>::template b<C>();

将常规规则应用于此类模棱两可的模板名称似乎并不困难。

假设同名对我很重要。我能以某种方式使这项工作吗?

最佳答案

Why?



答案在问题的正文中。这适用于类和函数,因为在 C 中有一个单独的命名空间用于结构标记和函数标识符。如果 C++ 旨在与 C 代码互操作,则它必须保留此行为。只需要查看像 stat function 这样的 API服用 struct stat论证为什么 C++ 保留了此类代码的有效性。这种使用命名空间的方式只是与驻留在全局命名空间中的 C 代码内联(因此 ::statstruct ::stat 应在需要时继续工作)。

但是,在 C++ 中,类标记的标识符与常规标识符共享一个“命名空间”。因此,这种“hack”的有效性是通过 C++ 规范中的一个特例来实现的,该特例在类发生冲突时简单地隐藏类。

[basic.scope.hiding]

2 A class name or enumeration name can be hidden by the name of a variable, data member, function, or enumerator declared in the same scope. If a class or enumeration name and a variable, data member, function, or enumerator are declared in the same scope (in any order) with the same name, the class or enumeration name is hidden wherever the variable, data member, function, or enumerator name is visible.



C++ 的设计者认为这是一个好主意还是一个坏主意并不重要。有一些遗留代码应该继续被 C++ 编译器接受为有效的,以便于与某些系统进行互操作。

但是没有处理需要相同行为的模板的遗留代码。模板是完全 C++ 的构造(与 C 完全无关)。因此,语言设计没有外部约束来为模板名称添加更多特殊情况。所以它没有。

Suppose that having the same name is important to me. Could I somehow make this work?



没有办法让它发挥作用。

关于c++ - 为什么 C struct hack 不适用于 C++ 模板声明?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61667261/

相关文章:

C++ Opencl 包装器引用计数?

c++ - 当两个候选人具有相同的简历资格时,转换函数的初始化是否应该不明确?

c# - 从 C# 调用 C++ 模板函数

go - 重置结构的某些属性的惯用方法是什么?

c++ - 为什么我不能直接在临时对象上调用 operator() ?

html - 在模板中访问 vue 环境变量

c++ - 为什么只有有效的空可变参数包的模板格式错误?

c - 为什么不只在 header 中声明结构?这不会使 include-guards 变得不必要吗?

c - 访问结构内 union 中的变量

c++ - primary-expression before ']'错误含义