【问题标题】:Use of qualified name in function parameter在函数参数中使用限定名
【发布时间】:2010-12-11 14:38:47
【问题描述】:

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

【问题讨论】:

  • 那么现在的问题是什么?您是否仍然有兴趣找出为什么有人愿意这样做?
  • @Martin :如果您指的是我帖子的编辑部分,那么是的,我想听听您和其他人的意见,尤其是为什么有人会使用arr[T::count]

标签: c++ templates parameters qualified-name


【解决方案1】:

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

标识符可以是可选的 作为参数名称提供;如果 存在于函数定义中 (8.4),它命名一个参数(有时 称为“形式论证”)

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

每个声明符都包含一个 声明符ID;它命名标识符 这是声明的。 id的表达 declarator-id 应该是一个简单的 除声明外的标识符 一些特殊功能(12.3、12.4、 13.5) 以及模板特化或部分的声明 专业化(14.7)。声明者 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,则编译器会失败。

【讨论】:

  • @Martin... 我不太明白这句话的意思。你能解释一下吗?
  • 它说“是的,你可以在参数中有一个名字,但它必须是一个标识符(即它必须是不合格的)。
  • @Martin :我不认为它说“但它必须是一个标识符(即它必须是不合格的)”。此外,它与 parameter-declaration-clause 的语法相矛盾。
  • 它被 8.3/1 明确禁止:“除了定义其类之外的成员函数 (9.3) 或静态数据成员 (9.4) 之外,声明符 ID 不应被限定,定义或在其命名空间之外显式实例化命名空间的函数或变量成员,或在其命名空间之外定义显式特化,或作为另一个类或命名空间成员的友元函数的声明 (11.4)。”
  • 如果“可以提供标识符”并不意味着可选提供的内容必须是标识符,那么您将如何解释它们?我看不到如何反驳:声明符->直接->声明符->声明符-id->id-expression->unqualified-id->identifier.
【解决方案2】:

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

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

P.S:我不是 100% 确定。如果我错了,请纠正我。 :)


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

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

【讨论】:

  • 感谢您的参考帖子。我将研究这一点及相关点,并尝试理解它们。
【解决方案3】:

似乎我对这些部分的理解有误。代替该代码,我们可能可以编写以下代码(根据 C++ 标准):

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 2017-09-14
    • 2023-02-21
    • 1970-01-01
    • 2015-07-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多