在函数参数中使用限定名称

时间:2010-12-11 14:38:47

标签: c++ templates parameters qualified-name

根据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不再是一个参数(我猜)。

3 个答案:

答案 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)

据我所知,您的代码生成错误,因为

  

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

P.S:我不是百分百肯定。如果我错了,请纠正我。 :)


  

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

阅读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不再是参数了(我猜)。