【问题标题】:Code compiles in Visual Studio 2010 but shouldn't compile at all代码在 Visual Studio 2010 中编译,但根本不应该编译
【发布时间】:2012-03-22 09:50:13
【问题描述】:

以下源代码可以使用 Visual Studio 2010 正确编译:

namespace NS
   {
   class X
      {
      };   
   X Y(X str);
   } 

void myFun()
   {
   NS::X x;
   Y(x);
   }

(这是简化的代码,我自己的所有类和函数名称都已被 X、Y、... 替换)

我希望Y(x) 行编译失败,因为它应该是NS::Y(x)

本源代码使用以下命令编译

cl /c file.cpp

这里没有包含其他文件,没有其他命令行选项。

为什么要编译这个文件? VS2010中的错误?还是我(和我的其他 3 位同事)忽略了的东西?

【问题讨论】:

  • 用 g++ 试过这个并得到了undefined reference to NS::Y(NS::X)' - 所以也许它可能是 VS 中的一个错误..
  • @WeaselFox:完全不相关。您的错误是 链接器错误,因为未定义 NS::Y。这是典型的,可能会在完整设置的另一个文件中定义。
  • @MatthieuM。 - 是的,我意识到这一点,谢谢。

标签: c++ compiler-errors


【解决方案1】:

您遇到的问题是由于ADL (Argument Dependent Lookup)。

您的 sn-p 没有任何问题(除了链接器可能会抱怨 NS::Y 未定义这一事实),但它应该编译 - VS2012 正在按应有的方式处理 sn-p。

编译器会找到NS::Y,因为参数x (NS::X) 的类型在适当的范围内。


3.4.2 依赖于参数的名称查找 [basic.lookup.argdep]

  1. 当一个不合格的名字被用作后缀表达式时 函数调用(5.2.2),在此期间未考虑的其他命名空间 可以搜索通常的不合格查找(3.4.1),并且在那些 命名空间,命名空间范围的友元函数声明(11.4)不是 否则可能会发现。

    这些对搜索的修改取决于 参数(对于模板模板参数, 模板参数)。

  2. 对于函数调用中的每个参数类型 T,都有一组零个或多个关联命名空间和一组零个或多个 要考虑的关联类。

    命名空间集和 类完全由函数参数的类型决定 (以及任何模板模板参数的命名空间)。

【讨论】:

  • 你说得对,我刚刚也在维基百科上找到了它。棘手。我没想到这会奏效。
  • 那么是MSVS还是gcc的bug?
  • @LuchianGrigore 没有错误,sn-p 编译。链接器就是找不到NS::Y 的定义。构建可执行文件有几个步骤。
  • @LuchianGrigore 两者都不是。 MSVC 不会出错,因为它只编译到目标文件。 g++ 错误来自链接器,而不是编译器。
  • 哦,我的错,我虽然它是用 MSVS 而不是 gcc 编译的。完全误解了这个问题。链接器错误很明显,不是我所怀疑的。
【解决方案2】:

这是有效的 C++ 代码。编译自 argument-dependent lookup 应用在这里。

【讨论】:

    猜你喜欢
    • 2011-05-21
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    • 2015-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-20
    相关资源
    最近更新 更多