首页 > 解决方案 > c ++命名空间的奇怪行为

问题描述

这是一些代码,显示了奇怪之处:

namespace ns
{
  typedef int int_type;

  class classus {
    public: 
      int a = 0;
  };

  void print(classus c){
    printf("a equals %i \n", c.a);
  }
  void print(int_type a){
    printf("a equals %i \n", a);
  }
}

int main(int argc, char* argv[])
{
  ns::int_type a1 = 2;
  ns::classus a2;
  ns::print(a1); // this line wont work without explicit ns:: scope
  print(a2); // this line works with or without explicit ns:: scope
}

它在 Visual Studio 2017 上构建和运行。Intellisense 也非常满意。

似乎包含在命名空间中的类变量会污染该命名空间范围的整行。这是错误还是功能?无论哪种方式,是否有一些关于此的文档...没有找到任何

标签: c++visual-c++namespaces

解决方案


让您感到困惑的功能称为 ADL(参数相关查找)

cppreference

依赖于参数的查找,也称为 ADL 或 Koenig 查找,是用于在函数调用表达式中查找非限定函数名称的一组规则,包括对重载运算符的隐式函数调用。除了通常的非限定名称查找所考虑的范围和名称空间之外,还会在其参数的名称空间中查找这些函数名称。

依赖于参数的查找使使用在不同命名空间中定义的运算符成为可能。

在您的示例a2中,来自命名空间ns足以让编译器ns在查找print.

您的示例中有趣的部分是它int_type也来自ns,尽管它只是一个 typedef 并且int没有在 中声明ns。考虑 typedef 不会引入新类型(而是别名)。所以a2真的是一个int

PS:这不是特定于 Visual Studio。任何符合标准的编译器都应该接受发布的代码。


推荐阅读