实际上,下面的代码不能用这个命令用Clang编译:
clang-std=c 11test.cc-o test
.
我只想模仿与C中的“交换习惯用法”相同的行为,使用“using directive”来启用ADL。但是下面的代码哪里错了呢?预期的调用优先级应为:N1::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{});
}
错误消息:
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.
更新:
我将N2::foo更改为可以在某种程度上模仿std::交换的模板方法。所以,这里的问题是为什么::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.
}
首先,您有一个普通的查找,它从内部作用域到外部作用域进行搜索,并在第一次匹配时停止,从后面的作用域隐藏重载。然后,当触发ADL时,它将向搜索中添加其他关联实体和名称空间。
因此,在您的情况下,ADL查找不会向重载集添加任何内容。
#include <iostream>
namespace N1 {
struct S {};
/*
void foo(S s) {
std::cout << "called N1::foo, specific one." << '\n';
}
*/
}
namespace N2 {
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{}); // ordinary lookup finds N2 in main scope and stops.
// adl lookup add N1 ns to the additionnal ns set but finds nothing
// overload set = N2::foo by ordinary lookup
}
现在,如果我取消注释您的S1版本,它就赢了!这就是你得到的:
#include <iostream>
namespace N1 {
struct S {};
void foo(S s) {
std::cout << "called N1::foo, specific one." << '\n';
}
}
namespace N2 {
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{}); // ordinary lookup finds N2 in main scope and stops
// adl lookup add N1 ns to the additionnal ns set and finds N1::foo
// overload set = N2::foo by ordinary lookup, N1::foo by ADL, N1::foo wins
}
交换也会得到同样的结果。在本例中,使用Foo::swap是因为它位于N1命名空间中:
#include <iostream>
namespace N1 {
struct Foo {
};
void swap(Foo& , Foo&) {
std::cout << "swap Foo" << std::endl;
}
}
namespace N2 {
struct S {
N1::Foo f;
};
void swap(S& l,S& r) {
using std::swap; // overload set is std::swap by ordinary lookup
swap(l.f, r.f); // and Foo::swap by ADL, Foo::swap wins
}
}
int main() {
N2::S s1,s2;
swap(s1,s2);
}
但是,如果在全局ns中移动特定于Foo的交换,则调用:
#include <iostream>
namespace N1 {
struct Foo {
};
}
void swap(N1::Foo& , N1::Foo&) {
std::cout << "swap Foo" << std::endl;
}
namespace N2 {
struct S {
N1::Foo f;
};
void swap(S& l,S& r) {
using std::swap; // overload set is std::swap by ordinary lookup
swap(l.f, r.f); // because ADL does not add the global ns to the
// ns to be searched for
}
}
int main() {
N2::S s1,s2;
swap(s1,s2);
}
在这种情况下,普通名称查找找到N2::foo
,ADL找到N1::foo
,它们都被添加到重载集中,然后执行重载解析并且调用不明确。
顺便说一句:如果没有使用N2::foo;
在main()
中,::foo
将通过正常名称查找找到,并且N1::foo
也被ADL找到;因此调用仍然是模棱两可的。
更新:
因此,这里的问题是为什么主函数中的“foo(N1::S{});
”不能调用::foo
?
因为随着使用N2::foo;的的使用,名称
N2::foo
被引入main
函数中。当调用foo
时,名称N2::foo
将在main
的范围内找到,然后名称查找停止,进一步的范围(全局命名空间)将不会被检查,因此::foo
根本不会被找到并添加到重载集中。结果N2::foo
都被调用。
名称查找如下所述检查范围,直到它找到至少一个任何类型的声明,此时查找停止并且不再检查其他范围。
顺便说一句:如果您将
使用N2::foo;
放在全局命名空间中main
之前,foo(N1::S{});
将调用::foo
。N2::foo
和::foo
都可以通过名称查找找到,并且::foo
在重载解析中获胜。
现场直播
所以我有家长和孩子班。我希望他们输出一些字段的值(如果存在),并且存在问题。 子类具有字段“name”,但结果具有两个字符串“name 不存在”。此外,如果父类中有名称,则第二个字符串无论如何都将是“名称不存在”。 我设法捕获了错误:IllegalAccessException-父类无法访问子字段,尽管子字段是打开的,还有“名称”字段。它还告诉孩子的成员是最终的和私有的。 我做错了什么?我希望每个
问题内容: 在代码底部运行的示例需要很长时间才能在我的机器上解决: 这是代码: 每只只供三只骆驼。我想至少这样做4次。该测试用例仍在运行(现在:()已经大约5分钟了。如果完成,我将对其进行更新。 我应该怎么做才能改善这段代码?(通常以性能为依据,但也欢迎其他建议)。 问题答案: 我以前也被这个绊倒了。这里的瓶颈实际上是。 该in语句是如此易于使用,你忘记了它是线性搜索,而当你在列表上进行线性搜索时
如何在PHP Smarty中优化这段代码? 现在我有一个代码让我困惑,有一个简单的代码。 当我搜索需要推送值的代码时。 优化如何发挥作用?我能写到数组吗?如果它可以写入数组,我该怎么办?
我已经开始学习JavaScript,我试图制作一个加载条的动画,但我不知道如何使它在条到达终点后重复这个功能,我想也许通过一个循环我可以得到我想要的结果,但我仍然在学习循环,我尝试了不同的方法,改变了整个代码,但没有任何效果。 有人能帮我吗?谢谢你抽出时间。
你好,我是java的新手,我对如何编写JUnit测试感到困惑,有人能帮忙吗? 任务说明: 当您将自动取款机(ATM)与银行卡一起使用时,您需要使用个人识别码(PIN)来访问您的帐户。如果用户在输入PIN码时失败三次以上,机器将阻止该卡。 假设用户的PIN是“1234”,编写一个程序,向用户索要PIN不超过三次,并执行以下操作: 如果用户输入了正确的号码,请打印一条消息,说明“您的PIN是正确的”,
使用djanog的异步如何改写下边这段代码: