将函数定义为静态成员和free之间会产生什么差异?

时间:2012-06-28 09:24:26

标签: c++ overloading

请考虑以下代码段:

#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的第二次声明以及这些声明之间的区别是什么?

2 个答案:

答案 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)之前移动这个函数。