前几天我无意中发现了这个问题,不知道哪个答案是正确的,或者两者是否都可以接受。
具体来说,我指的是在 OtherFunction 中对 bar(T{}) 的调用。从我能够在编译器资源管理器上进行的测试来看,这个决定似乎是 split 的。 msvc 和 icc 同意它是模棱两可的,而 gcc 和 clang 编译代码没有问题。
隐藏命名空间内的功能栏通过参数相关查找变得可见。此外,msvc/icc 将全局命名空间中的 bar 声明视为候选者,而 gcc/clang 则不考虑。似乎不应该考虑全局命名空间中的声明,因为它是在调用 bar(T{}) 之后声明的,但我不确定我是否正确阅读了不合格名称查找的规则,或者标准是否是在这方面模棱两可。
编辑: 看起来 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 declarationswith 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/