【问题标题】:Why does `using A::f` not work as expected?为什么“使用 A::f”不能按预期工作?
【发布时间】:2014-06-20 03:46:56
【问题描述】:

下面的代码被VC++和clang拒绝了。

为什么using A::f 没有按预期工作?

有没有办法在给定的命名空间中隐藏一些名字?

namespace A
{
    int f()
    {
        return 1;
    }
};

namespace B
{
    int f()
    {
        return 2;
    }
};

using namespace A;
using namespace B;

using A::f; // I want to hide B::f and only use A::f, how to do?

int main()
{
    auto n = f(); // error : call to 'f' is ambiguous
}

【问题讨论】:

  • 你能想出一个标题,它不会要求未来的访问者按照你找到它的方式来命名他们的命名空间和变量吗?
  • 您为什么希望它起作用? f()s 都是可见的。此外,命名空间的右大括号后不需要分号。
  • 这里的 using 声明完全是多余的。
  • C++ using 不是 Java import。在 Java 中,您可以执行类似 import java.util.*; import java.sql.*; import java.sql.Date; 的操作并消除歧义。在 C++ 中你不能。

标签: c++ namespaces using


【解决方案1】:

标准规定了using 指令的解释。强调我的:

using-directive 指定指定命名空间中的名称可以在 using-directive 出现在 using-directive 之后。 在非限定名称查找 (3.4.1) 期间,名称出现 好像它们是在最近的封闭命名空间中声明的,其中包含 using-directive 和 命名空间。 [ 注意: 在此上下文中,“包含”是指“直接或间接包含”。 - 结尾 注意]

(C++11 §7.3.4/2)

因此,之后

using namespace A;
using namespace B;

对名称f 的非限定查找会找到A::fB::f 就好像它们已在全局命名空间中声明。声明 using A::f 以相同的方式将名称 f 引入全局命名空间(尽管不同之处在于它实际上使 A::f 成为全局命名空间的成员),因此就非限定查找而言它是多余的。关键是 f 的非限定名称查找会在同一声明区域中找到 A::fB::f

解决方案?

int main()
{
    using A::f;
    auto n = f(); // no longer ambiguous; finds A::f
}

非限定名称查找首先查找的是main 的块范围,因此它只会找到A::f,即使如果搜索A::fB::f 都会在封闭的命名空间范围内找到.

【讨论】:

    【解决方案2】:

    因为这个:

    using namespace A;
    using namespace B;
    

    f 两个函数都在范围内。它们具有相同的签名,那么您期望会发生什么?

    这个 using 指令:

    using A::f();
    

    是多余的。

    【讨论】:

    • 显然 OP 很困惑,因为他们神奇地期望冗余指令覆盖 using namespace B
    • @djechlin:好吧,那是错误的,我是这么说的。你想说什么?你只是不喜欢我的措辞吗?确实我没有去规范。
    • 首先我在您编辑之前写了评论。但你的原话是“你期望会发生什么?”我觉得这个问题很明显,而且很明显,它清楚地表明使用两个命名空间确实不是重点(所以在你编辑之前它实际上是一个严格正确但无用的答案)。 OP 想知道为什么多余的 using 没有做任何事情,一个非常好的答案是“它只是没有”(在您的编辑中进行了解释)。
    • 我认为没有必要引用规范。基于这种误解,可能OP有一个更复杂的问题,将其缩小到那个例子,并且很惊讶它值得在SO或权威的地方确认。对于 OP 来说,这种行为可能比“它是多余的”更微妙。也许是“您必须先使用 using A::f 以避免以后发生冲突。”或其他一些微妙之处。
    猜你喜欢
    • 2021-05-30
    • 2020-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多