名字空间探讨!

jn989 2009-05-04 11:18:29
前两天看Sutter的Exceptional C++时,遇到一个有关名字空间问题,不甚明白,发上来问问大家:
书中有个Myers Example的例子:

namespace NS {
class T {};//typically from some header T.h
void f(T);
}

void f(NS::T);

int main()
{
NS::T parm;
f(parm);//ambiguous:NS::f or global f?
}

有关命名空间的问题我也知道了一些(primer 3版中有关名字空间的部分),但这里f(parm)函数调用怎么就二义性了呢?我知道C++中有这样一个名字查找规则--"如果在声明函数的参数时使用了一个类,那么在查找匹配的函数名字时,编译器会在包含参数类型的名字空间中也进行查找"。所以在解释f(parm)时,肯定会检查parm所在的空间NS的,再根据嵌套名字空间的隐藏原则,NS::f应该隐藏掉全局的void f(NS::T)啊!为什么就二义了呢?我理解的是main中的f(parm)是把NS空间当成局部空间解释的,就好像在main中自己定义的一样,这样的话不就隐藏了全局的f了吗?像下面一样:

char* format( int );
void g()
{// 全局函数format( int ) 被隐藏
char* format( double );
char* format( char* );
format(3); // 只有一个可行函数: format( double )
}

欢迎大家指教,谢谢!
...全文
198 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jinhao 2009-05-04
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 jn989 的回复:]
2.那你的意思是说koenig查找是在正常名字查找之后作为补充,最后才进行的吗?也就是说koenig的调用顺序问题了。
[/Quote]
可以这么说。只和名字查找的循序有关,但最后,这些被查找到的函数名都会选出来寻找最佳匹配,而不是说koenig的查找就有优先匹配权。
Paradin 2009-05-04
  • 打赏
  • 举报
回复
up
jn989 2009-05-04
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 Jinhao 的回复:]
名字查找规则很简单,但根据环境的不同就很繁琐。也不是所有情况都是一层层向外查找。

这里的查找很简单,首先,不要考虑用koenig查找。你会找到全局里的f。所有都找遍了之后,再考虑用koenig查找。然后你会找到NS::f。koenig查找在C++标准里叫做Argument-dependent name lookup,这种叫法应该更明确。

这时你再将所有的f合起来看,能找到哪个最佳匹配。koenig也不是在任何时候会进行,

C/C++ code
namespace NS {

[/Quote]
谢谢
1.你的那行代码应该调用的是A::f吧,因为看书的时候,好像是说成员函数要比非成员函数的关联性更强。不知对不对?
2.那你的意思是说koenig查找是在正常名字查找之后作为补充,最后才进行的吗?也就是说koenig的调用顺序问题了。
ps:你的那篇blog我看了,很好,很受启发,是有关模板上的应用,谢谢
adventurelw 2009-05-04
  • 打赏
  • 举报
回复
NS::f(T)对f(NS::T)的覆盖只发生在NS中,出了这个区域,就没有所谓的覆盖了——也即在NS
中调用f(T)时,一定是NS::f(T)这个。
因为main不是在NS中,自然不会发生所谓的覆盖

不过我还真不知道不用作用域解析符也能调用NS中的函数....学习了。。
Jinhao 2009-05-04
  • 打赏
  • 举报
回复
名字查找规则很简单,但根据环境的不同就很繁琐。也不是所有情况都是一层层向外查找。

这里的查找很简单,首先,不要考虑用koenig查找。你会找到全局里的f。所有都找遍了之后,再考虑用koenig查找。然后你会找到NS::f。koenig查找在C++标准里叫做Argument-dependent name lookup,这种叫法应该更明确。

这时你再将所有的f合起来看,能找到哪个最佳匹配。koenig也不是在任何时候会进行,

namespace NS {
class T {};//typically from some header T.h
void f(T);
}

struct A
{
A()
{
NS::T t;
f(t); //哪个f?
}

void f(NS::T);
};

或者还有更复杂的环境
http://blog.csdn.net/Jinhao/archive/2008/09/03/2875776.aspx
jn989 2009-05-04
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 Jinhao 的回复:]
这里没有名字隐藏。他们的调用和定义都不在一个域中。

如果没有koenig名字查找。那么main里面的,f(parm);,这个函数调用全局的。
如果有了koenig名字查找,则会查找到param类型所在的域的同名函数,也就是说
f(param);
先查找到全局的f,然后继续查找到NS::f,因此发生二义性
[/Quote]
谢谢
但是“如果有了koenig名字查找,则会查找到param类型所在的域的同名函数,也就是说
f(param);
先查找到全局的f,然后继续查找到NS::f,因此发生二义性”
这句不明白,名字查找过程是逐级的一层层向外的,所以“查找到param类型所在的域的同名函数”后就确定了调用者还用向外层(全局)查找吗?
而且感觉也应该是先查到NS::f,再全局f啊?
liliangbao 2009-05-04
  • 打赏
  • 举报
回复
帮顶~~·
Jinhao 2009-05-04
  • 打赏
  • 举报
回复
这里没有名字隐藏。他们的调用和定义都不在一个域中。

如果没有koenig名字查找。那么main里面的,f(parm);,这个函数调用全局的。
如果有了koenig名字查找,则会查找到param类型所在的域的同名函数,也就是说
f(param);
先查找到全局的f,然后继续查找到NS::f,因此发生二义性
jn989 2009-05-04
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 Jinhao 的回复:]
引用 6 楼 jn989 的回复:
2.那你的意思是说koenig查找是在正常名字查找之后作为补充,最后才进行的吗?也就是说koenig的调用顺序问题了。

可以这么说。只和名字查找的循序有关,但最后,这些被查找到的函数名都会选出来寻找最佳匹配,而不是说koenig的查找就有优先匹配权。
[/Quote]
恩,确实如此,刚才我又返回去看了看primer中有关函数重载->候选函数一节的叙述,更理解到koenig只是在选择候选函数时应用的,最终匹配是在这个过程完成后才进行的。
恩,问题解决了,谢谢你。
amossavez 2009-05-04
  • 打赏
  • 举报
回复
jihao的那篇博客很好呀,值得一看!

65,189

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧