根据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 compiles完美无缺。但是,我并不完全满意,因为T :: count不再是一个参数(我猜)。
答案 0 :(得分:2)
它无效。语法允许任意声明符,但8.3.5p8表示
标识符可以选择 作为参数名称提供;如果 出现在函数定义中 (8.4),它命名一个参数(有时 被称为“正式论证”)
编辑另一个语法限制声明符的引用(8.3p1,[dcl.meaning]):
每个声明者只包含一个 声明符-ID;它命名标识符 宣布的。 id的表达式 声明者id应该是一个简单的 除声明外的标识符 一些特殊功能(12.3,12.4, 13.5)和模板专业化的声明或部分 专业化(14.7)。声明者ID 除非是 成员函数的定义(9.3) 或静态数据成员(9.4)或嵌套 班级(9.7)以外的班级 定义或显式实例化 函数,变量或类 它之外的命名空间的成员 命名空间,或者a的定义 以前宣布明确 它之外的专业化 命名空间,或声明 作为成员的朋友功能 另一个类或命名空间(11.4)。
因此,在参数声明中,您不能使用限定名称。
编辑:在编辑后的表单中,函数参数类型衰减到int*
,甚至在进行测试之前,T::count
是否实际存在并且是一个整数常量。如果您想要一个示例,其中此类签名中的限定名称将执行有意义的操作,请考虑
template<class T>
struct sample
{
void fun(int S=T::count);
};
当没有参数调用fun
时,编译器需要确定默认参数,如果T
没有count
成员,或者无法转换为{{}},则会失败。 {1}}。
答案 1 :(得分:1)
据我所知,您的代码生成错误,因为
P.S:我不是百分百肯定。如果我错了,请纠正我。 :)$ 8.3 / 1:当declarator-id被限定时,声明应引用先前声明的限定符所引用的类或命名空间的成员,并且该成员不应被引入通过声明者id的nested-name-specifier指定的类或命名空间范围内的using声明。 [注意:如果限定符是global :: scope解析运算符,则declarator-id引用在全局命名空间范围内声明的名称。 ]
在什么情况下,使用限定名称(在函数参数列表中)可能是有利的?
阅读Herb Sutter的Exceptional C ++中的第31和32项。这两个项目都涉及Koenig查找和接口原则。
答案 2 :(得分:0)
我似乎错误地理解了这些部分。我们可以编写以下代码(根据C ++标准)而不是代码:
template<class T>
struct sample
{
void fun(int arr[T::count]);
};
gcc-4.3.4 compiles完美无缺。但是,我并不完全满意,因为T::count
不再是参数了(我猜)。