参数中的前向声明与“普通"声明之间的差异.前瞻性声明 [英] Difference between forward declaration in argument vs "normal" forward declaration

查看:81
本文介绍了参数中的前向声明与“普通"声明之间的差异.前瞻性声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(模板)自变量中的前向声明(使用

What is - if any - the difference between a forward declaration in a (template) argument (using an elaborated type specifier) and a "normal" forward declaration?

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 ++标准而言,没有向前声明之类的东西.只有声明.

Let's begin by noting that "forward declaration" is a colloquialism used to refer to a certain common practical use of certain kinds of declarations. There is no such thing as a forward declaration as far as the C++ standard is concerned. There are just declarations.

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

With that in mind, I believe that there is no difference between

void foo(struct bar *);

struct bar;

就其对名称bar的影响而言.如果没有先前的声明,则这两个声明最终都会引入struct bar的名称.

as far as their effect on the name bar is concerned. Both declarations end up introducing the name of the struct bar if there is no previous declaration that already did so.

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

The relevant paragraph in C++17 would seem to be [basic.lookup.elab]/2 (emphasis mine):

如果 class-key 引入了精心设计的类型说明符,并且此查找未找到先前声明的 type-name ,或[…] 精加工类型说明符是一个声明,它引入了[basic.scope.pdecl中描述的类名 ].

If the elaborated-type-specifier is introduced by the class-key and this lookup does not find a previously declared type-name, or […] the elaborated-type-specifier is a declaration that introduces the class-name as described in [basic.scope.pdecl].

如果遇到的修饰类型说明符不包含嵌套名称说明符,则将执行非限定名称查找以查看该名称是否已命名相应的类型.如果未找到先前声明的名称,则 elaborated-type-specifier 成为该名称的类类型的声明…

If an elaborated-type-specifier that doesn't contain a nested-name-specifier is encountered, unqualified name lookup is performed to see if the name already names a corresponding type. If no previously declared name is found, then the elaborated-type-specifier becomes a declaration of the class type of that name…

正如geza所指出的那样,可能存在差异的一种方式与引入名称的范围有关.虽然

As pointed out by geza, the one way in which there can be a difference has to do with the scope into which the name is introduced. While

struct bar;

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

always introduces the name into the scope in which the declaration appears, an elaborated-type-specifier appearing as part of any other kind of declaration will introduce the name into the closest enclosing namespace [basic.scope.pdecl]/7.

这篇关于参数中的前向声明与“普通"声明之间的差异.前瞻性声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆