【问题标题】:Inferring namespace of freestanding function推断独立函数的命名空间
【发布时间】:2023-03-29 07:18:01
【问题描述】:

命名空间限定问题:为什么下面没有推断出函数的命名空间?

namespace X {

void func(int) {}

struct Z{
   void func(){
      //func(int{}); does not compile
      X::func(int{}); // this works
   }
};

}

int main() {
   X::Z z;
   z.func();
}

【问题讨论】:

  • 这与命名空间无关;不合格的名称查找找到Z::func 并停止查找。粗略地说,非限定名称查找在当前范围内查找名称,然后向外搜索其封闭范围;一旦找到该名称的声明,它就会停止。即使这样找到的实体后来被发现在原始上下文中不可用。另一种思考方式:Z::funcX::func 隐藏在Z 类的范围内,因此需要一个限定名来引用X::func
  • 如果你给Z的成员函数起一个不同的名字,你会发现普通的func(0)可以工作。
  • @IgorTandetnik 这对我来说确实像是一个答案。
  • 感谢@IgorTandetnik,这里的关键似乎是查找仅基于名称而不是整个签名

标签: c++ namespaces


【解决方案1】:

C++ 的这个特定部分可以是generally called "unqualified name lookup"。该术语描述了在 C++ 程序中获取单个标识符,然后确定它所引用的实际类型、对象、函数或类。

例如,在 C++ 程序中可以有很多东西叫做rosebud,所以

rosebud();

This 可以引用同名的类方法,并调用它。或者这可能是一个带有重载() 运算符的对象,它调用它。在不同的命名空间中也可能有一个名为 rosebud() 的东西。非限定名称查找指定此特定 rosebud 引用其中的哪一个。

struct Z{
   void func(){

这里我们使用了Z 类的方法。非限定名称查找首先查找属于此类成员的标识符。 只有在没有找到的情况下才会在全局命名空间中进行非限定名称查找,以查看是否存在。

      func(int{}); // does not compile

好吧,这个类中恰好有一个名为func 的方法,所以这个func 的非限定名称查找解析为这个方法。这失败了,因为 func 方法没有参数。

不合格名称查找考虑不合格标识符的确切位置。当它出现在一个类中时,非限定名称查找首先搜索该类的成员。

尽管在全局范围内还有一个func 函数,但不合格的查找会找到类方法,仅此而已(引用引用的链接):

[unqualified] 名称查找检查如下所述的范围, 直到找到至少一个任何类型的声明,此时 查找停止,不再检查范围。

路的尽头。全局命名空间中还有一个 func 的事实并不重要。对于不合格的名称查找,一旦找到“某物”,它就会更好地工作,否则。

这些只是非限定名称查找规则之一。

X::func(int{}); // this works

嗯,是的。这在 X 命名空间中显式引用了 func。此符号(部分)由显式命名空间引用限定。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-07-19
    • 2010-11-04
    • 1970-01-01
    • 2014-05-14
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多