YHS*_*SPY 6 c++ name-lookup argument-dependent-lookup
实际上,使用此命令无法使用 Clang 编译以下代码:
clang++ -std=c++11 test.cc -o test.
我只想模仿与 C++ 中的“交换习语”相同的行为,以使用“使用指令”来启用 ADL。但是下面的代码我哪里错了?预期的呼叫优先级应该是:N1::foo> N2::foo> ::foo,对吗?
namespace N1 {
struct S {};
void foo(S s) {
std::cout << "called N1::foo.";
}
}
namespace N2 {
void foo(N1::S s) {
std::cout << "called N2::foo.";
}
}
void foo(N1::S s) {
std::cout << "called foo.";
}
int main() {
using N2::foo;
foo(N1::S{});
}
Run Code Online (Sandbox Code Playgroud)
错误信息:
test.cc:54:3: error: call to 'foo' is ambiguous
foo(N1::S{});
^~~
test.cc:40:8: note: candidate function
void foo(S s) {
^
test.cc:45:8: note: candidate function
void foo(N1::S s) {
^
1 error generated.
Run Code Online (Sandbox Code Playgroud)
更新:
我将 N2::foo 更改为模板方法,该方法可以在一定程度上模仿 std::swap 。那么,这里的问题是为什么::foo不能foo(N1::S{});在main函数中被“ ”调用?因为当它们具有相同的优先级时,该函数应该比要调用的模板函数更合适。
namespace N1 {
struct S {};
/*
void foo(S s) {
std::cout << "called N1::foo, specific one." << '\n';
}
*/
}
namespace N2 { // as a fallback to unqualified name which has no user-defined overload.
template<typename T>
void foo(T) {
std::cout << "called N2::foo, generic one." << '\n';
}
}
void foo(N1::S s) {
std::cout << "called foo." << '\n';
}
int main() {
using N2::foo;
foo(N1::S{});
foo(10); // use generic version.
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,正常名称查找会找到 和N2::foo,并且被ADLN1::foo找到,它们都被添加到重载集中,然后执行重载解析,并且调用是不明确的。
BTW:如果没有using N2::foo;in main(),::foo将通过正常的名称查找找到,并且N1::foo也可以通过 ADL 找到;结果,调用仍然不明确。
更新:
那么,这里的问题是为什么函数中不能被“”
::foo调用呢?foo(N1::S{});main
因为随着 的使用using N2::foo;,名称N2::foo被引入到main函数中。当调用foo名称时,N2::foo将在 的范围内找到名称main,然后名称查找停止,将不会检查进一步的范围(全局名称空间),因此::foo根本不会被发现并添加到重载集中。N2::foo因为这两种情况都需要结果。
名称查找按如下所述检查范围,直到找到至少一个任何类型的声明,此时查找停止并且不再检查其他范围。
顺便说一句:如果您using N2::foo;在之前放入全局命名空间main,foo(N1::S{});则会调用::foo. 和N2::foo都是::foo通过名称查找找到的,并::foo在重载解析中获胜。
| 归档时间: |
|
| 查看次数: |
77 次 |
| 最近记录: |