c++ - 这个函数调用应该是模棱两可的吗?

标签 c++ argument-dependent-lookup function-templates name-lookup

前几天我无意中发现了这个问题,不知道哪个答案是正确的,或者两者是否都可以接受。

具体来说,我指的是在 OtherFunction 中对 bar(T{}) 的调用。从我能够在编译器资源管理器上进行的测试来看,这个决定似乎是 split 的。 msvc 和 icc 同意它是模棱两可的,而 gcc 和 clang 编译代码没有问题。

隐藏命名空间内的功能栏通过参数相关查找变得可见。此外,msvc/icc 将全局命名空间中的 bar 声明视为候选者,而 gcc/clang 则不考虑。似乎不应该考虑全局命名空间中的声明,因为它是在调用 bar(T{}) 之后声明的,但我不确定我是否正确阅读了不合格名称查找的规则,或者标准是否是在这方面模棱两可。

https://godbolt.org/z/HAS-Cv

编辑: 看起来 msvc 已经修复了这个问题,只要使用/permissive- 选项 ( https://devblogs.microsoft.com/cppblog/two-phase-name-lookup-support-comes-to-msvc/ )

template <typename T>
inline void OtherFunction () {
    bar(T{});
}

namespace hidden {
    struct Foo {};
    inline void bar (Foo foo) {}
}

inline void bar (hidden::Foo foo) {}

void Function () {
    OtherFunction<hidden::Foo>();
}

最佳答案

Gcc 和 Clang 是正确的。 name lookup 找不到在 OtherFunction 定义之后定义的全局 bar ;而 hidden::bar 可以通过 ADL 找到.

(强调我的)

For a dependent name used in a template definition, the lookup is postponed until the template arguments are known, at which time ADL examines function declarations with external linkage (until C++11) that are visible from the template definition context as well as in the template instantiation context, while non-ADL lookup only examines function declarations with external linkage (until C++11) that are visible from the template definition context (in other words, adding a new function declaration after template definition does not make it visible except via ADL).

关于c++ - 这个函数调用应该是模棱两可的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56502624/

相关文章:

c++ - 从基类继承函数声明中参数的默认值

c++ - 模板构造函数重载问题

c++ - 使用基类的函数模板特化

c++ - 模板参数推导(在同一调用中同时使用显式和隐式参数)

c++ - 工厂方法模式

c++ - 找到最大元素的位置

c++ - 无法理解 int 和用户定义类型之间的名称查找差异 - 可能与 ADL 相关

c++ - 函数查找和命名空间

c++ - 迭代器概念弱于相应的命名需求,哪些适用于非范围标准算法?

c++ - 解决参数依赖查找歧义的非侵入性方法