2011-04-29 84 views
10

Doubt originated from here通过全局函数选择的同名类静态成员函数?


int g() { 
    cout << "In function g()" << endl; 
    return 0; 
} 

class X { 
public: 
    static int g() { 
    cout << "In static member function X::g()" << endl; 
    return 1; 
    } 
}; 

class Y: public X { 
    public: 
    static int i; 
}; 

int Y::i = g(); 

最初我虽然,作为符号解析从最内范围外最范围发生,这就是为什么X ::克()将被调用。
但后来我仔细注意到代码

int Y::i = g(); 

我们如何能够访问X ::克()没有名称范围?
此语句所在的范围应该是全局的,而不是Y ::或X ::,所以符号解析应该给出函数g()的全局版本?

+1

如果你想全局函数使用'::克()' – 2011-04-29 09:13:22

回答

11

注:我觉得我以前的答案是错误的它不是Koenig Lookup即参数相关的名称查找(ADL),所以我删除了(前面)的答案,因为我发现,从标准的相关部分,回答你的。问题。

Your c ode直接来自C++ 03标准的§9.4/ 2节。

静态成员可直接在其类或 的范围从一等级类派生 (第10节)的范围被称为 ;在此 情况下,静态成员被称为 仿佛使用的合格-ID表达 ,与嵌套名称说明符合格-ID命名类 范围从该静态成员是 引用的 。

然后,它给出了这样的例子(你问的问题)

[Example: 

    int g(); 
    struct X { 
     static int g(); 
    }; 
    struct Y : X { 
     static int i; 
    }; 
    int Y::i = g(); // equivalent to Y::g(); 

—end example] 

然后,它说,在§9。4/3

如果不合格-ID(5.1)在 使用静态构件 以下成员的声明符-ID的定义, 和名称查找(3.4.1)认定的 不合格-id表示静态 构件,枚举,或嵌套类型的 成员的类(或基类成员的类的 的),则 不合格-ID被变换成 合格-ID表达,其中 嵌套名称说明符命名分类s 范围成员 参考

因为,在静态成员的定义发生,这意味着Y::g()被称为只在初始化,而不是在分配

//definition-cum-initialization 
int Y::i = g(); // equivalent to Y::g(); 
int main() 
{ 
    //assignment 
    Y::i = g(); // does not equivalent to Y::g(); it calls global g() 
} 

看到输出这里:http://www.ideone.com/6KDMI

让我们考虑另一个例子:

struct B{}; 

B f(); 

namespace NS 
{ 
    struct A { static B b;}; 
    B f(); 
} 

//Definition cum Initialization 
B NS::A::b = f(); //calls NS::f() 
B b = f();   //calls global f() 

int main() 
{ 
    //Assignment 
    NS::A::b = f(); //calls global f() 
    b = f();  //calls global f() 
} 

在这里看到完整的演示:http://www.ideone.com/53hoW

+2

接受并完全理解。在你之前的回答中,我正在考虑这里的论点在哪里。无论如何,感谢让我意识到Koenig Lookup(我从来没有听说过),当然这个问题的答案。 – Amar 2011-04-29 18:09:42

9

这是因为您使用int Y::i =...,请注意Y::。这就是为什么,它实际上寻找g()里面Y,这是X::g(),因为Y派生X


增加:例如,如果你把int i = g();int Y::i = g();后,出现的结果将是:

In static member function X::g() 
In function g()

编辑:究竟 - 参数相关的名称查找。我不记得在开始时如何调用它。由于谢里夫的回答(:

EDIT2:OK,纳瓦兹找到了正确的解释,这是在标准,它似乎并没有被“自变量相关的名称查找”但逻辑仍然是 绝对的。 。同样

+0

+1:尽管纳瓦兹给规则的名称,他没有明确说范围来自'Y :: i'。 – 2011-04-29 09:10:02

+0

@Kiril,@Nawaz:我正在浏览n3242,我无法找到Koenig Lookup在这里适用的地方。 ** [class.static.data] **对此保持沉默。看起来很奇怪(虽然很明显是怎么回事),因为通常结果类型不参与查找和重载解析过程。你知道它在哪里吗? – 2011-04-29 09:43:05

+0

@Matthieu M. - 我没有,对不起。 – 2011-04-29 09:58:52