请考虑以下代码段:
#include <iostream>
using namespace std;
struct Element {
void SetVisible(bool) { cout << "Called SetVisible on Element" << endl; }
};
struct ElementQuery {
ElementQuery(Element * e) : element(e) { }
Element * Get() const { return element; }
Element * element;
};
namespace A {
static void SetVisible(ElementQuery const& element, bool show) {
cout << "Called SetVisible on ElementQuery" << endl;
SetVisible(element.Get(), show);
}
static void SetVisible(Element * element, bool show) {
element->SetVisible(show);
}
};
int main() {
Element * e = new Element();
ElementQuery q(e);
A::SetVisible(q, true);
delete e;
return 0;
}
运行时,由于调用SetVisible(element.GetFirst(), show)
中的无限递归,程序失败。正如我所假设的那样,因为函数SetVisible(Element * element, bool show)
在调用时尚未声明,尽管它更适合重载决策。
但是当我将namespace A
更改为struct A
,重新编译并运行时,一切正常。程序打印两行到cout
并正常结束。
我的问题是:为什么第二次调用“看到”SetVisible
的第二次声明以及这些声明之间的区别是什么?
答案 0 :(得分:1)
这是因为命名空间是按顺序处理的,并且Element和ElementQuery之间存在转换(因为你的构造函数不是显式的)。
这是更正后的代码
#include <iostream>
using namespace std;
struct Element {
void SetVisible(bool) { cout << "Called SetVisible on Element" << endl; }
};
struct ElementQuery {
explicit ElementQuery(Element * e) : element(e) { }
Element * Get() const { return element; }
Element * element;
};
namespace A {
static void SetVisible(Element * element, bool show) {
cout << "Called A::SetVisible on Element" << endl;
element->SetVisible(show);}
static void SetVisible(ElementQuery const& element, bool show) {
cout << "Called A::SetVisible on ElementQuery" << endl;
SetVisible(element.Get(), show);
}
};
int main() {
Element * e = new Element();
ElementQuery q(e);
A::SetVisible(q, true);
delete e;
return 0;
}
答案 1 :(得分:0)
看来这个代码根本不应该编译。因为这个电话: SetVisible(element.Get(),show); $ void SetVisible(Element *元素,bool show)在瞬间调用时不可见。你需要在$ void SetVisible(ElementQuery const&amp; element,bool show)之前移动这个函数。