【问题标题】:Exceptional C++[Bug]?特殊的 C++[错误]?
【发布时间】:2011-03-03 15:34:04
【问题描述】:

我一直在阅读Exceptional C++ by Herb Sutter。到达Item 32

我找到了以下

 namespace A 
 {
     struct X;
     struct Y;
     void f( int );
     void g( X );
 }
 namespace B
 {
     void f( int i )
     {
        f( i );   // which f()?
     }
 }

这个 f() 调用自身,无限递归。原因是唯一可见的 f() 是 B::f() 本身。

还有另一个函数签名为 f(int),即命名空间 A 中的函数。如果 B 写为 "using namespace A;" 或 "using A::f;",则 A ::f(int) 在查找 f(int) 时作为候选者是可见的,并且 f(i) 调用在 A::f(int) 和 B::f(int) 之间是不明确的。但是,由于 B 没有将 A::f(int) 纳入范围,因此只能考虑 B::f(int),因此该调用明确地解析为 B::f(int)。

但是当我执行以下操作时..

 namespace A 
 {
     struct X;
     struct Y;
     void f( int );
     void g( X );
 }
 namespace B
 {
     using namespace A;
     void f( int i )
     {
        f( i );   // No error, why?
     }
 }

这意味着 Herb Sutter 搞错了?如果不是,为什么我没有收到错误消息?

【问题讨论】:

  • 某事不是编译时错误并不意味着它具有明确定义的语义。
  • 但是写using A::f会导致编译时出错。
  • 根据您的图书版本,最长可达 11 年。 C++03 和 C++0x 中的任何更改都不会反映在其示例中。 (我不知道,但我怀疑这在他第一次写的时候有效。)

标签: c++


【解决方案1】:

using 声明 (using A::f) 和 using 指令 ​​(using namespace A) 之间存在细微差别。

using 声明将名称引入使用它的范围,因此 using A::fB::f(int) 的定义中对 f 的调用不明确。

using 定义使命名空间的成员在使用它的范围内可见,但它们出现就好像名称来自所引入的命名空间的最近的公共范围以及其中的命名空间使用了 using 指令。这意味着在这种情况下,using namespace A; 使另一个 f 看起来好像它是在全局范围内声明的,但它仍然被 B::f(int) 隐藏。

(ISO/IEC/BS 14882:2003 7.3.4 [namespace.udir] / 1 适用于所有标准爱好者。)

【讨论】:

    猜你喜欢
    • 2016-08-09
    • 2013-12-27
    • 1970-01-01
    • 2011-07-20
    • 1970-01-01
    • 2022-10-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多