调用 ADL 时,表达式和命名空间之间是否会发生冲突

Are collisions between expressions and namespaces expected when invoking ADL?

本文关键字:是否 冲突 之间 命名空间 ADL 表达式 调用      更新时间:2023-10-16

给定以下示例,我希望解析器将std识别为函数:

#include <algorithm>
namespace test
{
    class foo{};
    void std(foo f);
}
int main()
{
    std(test::foo());
    return 0;
}

但是,在 GCC 4.8.4 中,这会导致错误 - "错误:意外的命名空间名称'std':预期的表达式。

使用 clang 5.0,我得到"错误:意外的命名空间名称'std':预期的表达式">

这是意料之中的吗?我无法想象解析器在这里没有足够的上下文来区分表达式和命名空间?

编辑:示例使用应调用 ADL 的更复杂的类型。在我的实际用例中,代码是通用的,我需要 ADL。

没有 ADL 用于int

如果正常的非限定查找发现"既不是函数也不是函数模板的声明"(例如命名空间的声明(,则也没有 ADL。

由于几个原因,您的示例不起作用。

  1. 它不使用 ADL。 如果函数的参数是在命名空间中定义的类型,则将使用 ADL。例如

    namespace test
    {
       struct bar {};
       void foo(bar b) {}
    }
    // uses ADL to resolve to test::foo.
    foo(test::bar());
    
  2. std是一个命名空间。在没有任何其他作用域限定符的情况下使用时,它是命名空间的名称。因此,即使使用了命名空间中定义的类型,也不会使用 ADL。因此,以下内容也不正确。

    namespace test
    {
       struct bar {};
       void std(bar b) {}
    }
    std(test::bar());
    

请注意,您可以使用:

namespace test
{
   struct bar {};
   void std(bar b) {}
}
test::std(test::bar());