首页 > 解决方案 > 参数中的前向声明与“正常”前向声明之间的区别

问题描述

(如果有的话)(模板)参数中的前向声明(使用详细的类型说明符)和“正常”前向声明之间的区别是什么?

void foo(struct bar *);

// vs

struct bar;
void foo(bar *);

// ------ and also -------

std::unique_ptr<class Baz> one;

// vs

class Baz;
std::unique_ptr<Baz> two;

标签: c++language-lawyer

解决方案


让我们首先注意“前向声明”是一种口语,用于指代某些类型声明的某种常见实际用途。就 C++ 标准而言,没有前向声明之类的东西。只有声明。

考虑到这一点,我相信两者之间没有区别

void foo(struct bar *);

struct bar;

就它们对名称的影响bar而言。bar如果没有先前的声明已经这样做,则两个声明最终都会引入结构的名称。

C++17 中的相关段落似乎是[basic.lookup.elab]/2(强调我的):

如果类键引入了详细类型说明符并且此查找未找到先前声明的类型名称,或者 [...]详细说明类型说明符是一个引入类名称的声明,如 [ basic.scope.pdecl]。

如果遇到不包含嵌套名称说明符的详细类型说明符,则执行非限定名称查找以查看该名称是否已经命名了相应的类型。如果没有找到先前声明的名称,那么详细类型说明符将成为该名称的类类型的声明......

正如 geza 所指出的,可能存在差异的一种方式与引入名称的范围有关。尽管

struct bar;

总是将名称引入声明出现的范围,作为任何其他类型声明的一部分出现的详细类型说明符会将名称引入最近的封闭命名空间[basic.scope.pdecl]/7


推荐阅读