2

根据 C++ 标准,函数参数的名称由declarator-id解析,并且declarator-id也可以是限定名称。这意味着,以下代码是完全有效的(如果我正确理解了标准中的相关部分):

template<class T>
struct Sample
{
    int fun(int T::count); //T::count is qualified variable name
};

我的问题基本上是,为什么有人会写这样的代码?在什么情况下,使用限定名(在函数参数列表中)可能是有利的?


编辑:

看来我对这些部分的理解不正确。除了上面的代码,我们可能可以编写以下代码(根据 C++ 标准):

template<class T>
struct sample
{
  void fun(int arr[T::count]);
};

gcc-4.3.4完美编译。但是,我并不完全满意,因为 T::count 不再是参数(我猜)。

4

3 回答 3

2

这是无效的。语法允许任意声明符,但 8.3.5p8 说

可以选择提供标识符作为参数名称;如果出现在函数定义(8.4)中,它会命名一个参数(有时称为“形式参数”)

编辑另一个在语法上约束声明符的引用(8.3p1,[dcl.meaning]):

每个声明符只包含一个声明符id;它命名声明的标识符。declarator-id 的 id-expression 应该是一个简单的标识符,除了一些特殊函数的声明(12.3、12.4、13.5)和模板特化或部分特化的声明(14.7)。declarator-id 不应被限定,除非定义其类之外的成员函数 (9.3) 或静态数据成员 (9.4) 或嵌套类 (9.7),函数、变量或类成员的定义或显式实例化命名空间之外的命名空间的定义,或先前声明的在其命名空间之外的显式特化的定义,或作为另一个类或命名空间成员的友元函数的声明(11.4)。

所以在参数声明中,你不能使用限定名。

编辑:在编辑的形式中,函数参数类型衰减为int*,甚至在测试是否T::count实际存在并且是整数常量之前。如果您想要一个示例,其中此类签名中的限定名称会做一些有意义的事情,请考虑

template<class T>
struct sample
{
  void fun(int S=T::count);
};

fun不带参数调用时,编译器需要确定默认参数,如果T没有count成员,则默认参数失败,或者无法转换为int.

于 2010-12-11T14:57:13.943 回答
1

据我了解,您的代码格式不正确,因为

$8.3/1 :当 declarator-id 被限定时,该声明应引用该限定符所引用的类或命名空间的先前声明的成员,并且该成员不应由 using-declaration 在范围内引入由 declarator-id 的嵌套名称说明符指定的类或命名空间。[注意:如果限定符是全局 ::scope 解析运算符,则 declarator-id 指的是在全局命名空间范围内声明的名称。]

PS:我不是百分百确定。如果我错了,请纠正我。:)


在什么情况下,使用限定名(在函数参数列表中)可能是有利的?

阅读 Herb Sutter 的 Exceptional C++ 中的第 31 和 32 条。这两个项目都处理 Koenig 查找和接口原理。

于 2010-12-11T15:33:12.013 回答
0

看来我对这些部分的理解不正确。代替该代码,我们可能可以编写以下代码(根据 C++ 标准):

template<class T>
struct sample
{
  void fun(int arr[T::count]);
};

gcc-4.3.4 完美编译。但是,我并不完全满意,因为T::count不再是参数(我猜)。

于 2010-12-11T15:43:44.933 回答