函数参数的声明区域

时间:2015-01-30 17:57:51

标签: c++ templates language-lawyer

我们在N4296::3.3.9/2 [basic.scope.temp]中有以下示例:

namespace N {
    template<class T> struct A { };                 // #1
    template<class U> void f(U) { }                 // #2
    struct B 
    {
        template<class V> friend int g(struct C*);  // #3
    };
}
     

TUV的声明性区域是模板声明   分别为#1#2#3行。但名称AfgC都是   属于同一个声明区域 - 即 namespace-body   N

我不清楚为什么N的身体是gC的声明性区域。我以为是B级的身体 有人可以澄清标准的含义吗?

2 个答案:

答案 0 :(得分:4)

C首先在g中声明,因此[basic.scope.pdecl] /(7.2)适用

  

表格

详细类型说明符      

类键   标识符

     

如果在 decl-specifier-seq 中使用 elaborated-type-specifier 或   在命名空间作用域中定义的函数的 parameter-declaration-clause ,[...]; 否则,除了作为朋友声明之外,标识符在包含声明的最小名称空间或块范围中声明。

(“否则......”部分仅适用于friend class C;形式的声明;它使用“as”而不是“inside”)
因此,当C被声明为N的成员时,显然它的声明区域是N的正文。事实上,你是can use C outside B

g根据[namespace.memdef] / 3

N的成员
  

如果非本地类中的朋友声明首先声明[..]   功能模板朋友是最里面封闭的成员   命名空间。

因此g的声明性区域也是N的身体。

答案 1 :(得分:2)

由于g是友方函数,因此其范围是命名空间范围,根据11.3 朋友部分:

  

如果和,可以在类的朋友声明中定义函数   只有当类是非本地类(9.8)时,函数名才是   不合格,并且该函数具有命名空间范围。 [例如:

class M {
friend void f() { } // definition of global f, a friend of M,
// not the definition of a member function
};
     

-end example]

我们可以看到这也适用于7.3.1.2部分的功能模板:

  

如果非本地类中的朋友声明首先声明一个类,   功能,类模板或功能模板 97 的朋友   是最里面的封闭命名空间的成员。[...]

C这将在3.3.2声明部分

中介绍
  

首先在一个声明中声明一个类的声明   elaborated-type-specifier如下:

并包含以下项目符号(强调我的):

  
      
  • 表示

    形式的详细类型说明符      

    类密钥标识符

  •   
     

如果在decl-specifier-seq或中使用了elaborated-type-specifier   在命名空间作用域中定义的函数的parameter-declaration-clause,   标识符在名称空间中声明为类名   包含声明;