【问题标题】:Within a class in a namespace, can I exit **just** the class namespace?在命名空间中的类中,我可以退出 **just** 类命名空间吗?
【发布时间】:2015-04-14 12:46:52
【问题描述】:

此代码无法编译:

class A;

void foo(A&) {
}

class A {
    void foo() {
        foo(*this); ///This does not compile
    }
};

错误:

error: no matching function for call to 'A::foo(A&)'
         foo(*this);
                  ^
note: candidate is:
note: void A::foo()

这可以通过调用::foo(*this);来解决


但是,让我们考虑一下我们在命名空间中的情况:

namespace bar {

    class A;

    void foo(A&) {
    }

    class A {
        void foo() {
            foo(*this); ///This does not compile
        }
    };

}

除了显式调用bar::foo(*this);,还有其他方法吗?我的意思是,有没有办法在下一个周围的声明性区域中查找名称,即包含 bar 命名空间?

用例类似于here

【问题讨论】:

  • 有一种方法:将foos 中的一个重命名为其他名称,这样也可以为您节省一些不眠之夜。
  • 您的示例与此问题无关。这个例子是一个多态的例子,这是一个名称查找问题。
  • @NathanOliver 我更正了指​​向该问题的已接受答案的指针。
  • 我的评论还是一样。该解决方案使用多态性。
  • 虽然命名空间类似于文件系统中的目录,但没有等同于 ../。您得到的最接近的是 *this./

标签: c++ class namespaces


【解决方案1】:

我的意思是,有没有办法在下一个周围的声明性区域中查找名称, 即包含 bar 命名空间?

没有。

你可以反过来做:

void foo() {
    using bar::foo;
    foo(*this); /// OK now
}

【讨论】:

  • 为什么叫它the other way around
  • @Antonio 因为它将名称从外部范围带到内部,更窄的范围。
【解决方案2】:

不在方法本身内。但是,您可以在 .cpp 文件中执行此操作:

namespace bar {
  namespace {
    auto outerFoo = foo;
  }
  void A::foo() {
      outerFoo(*this);
  }
}

请注意,名称 outerFoo 是一个隐藏的实现细节,不会导致名称冲突(因为它位于匿名命名空间中)。

【讨论】:

  • 太棒了!我只是遗憾无法访问 C++11 auto,但万一我能绕过它。注意:这成为公认的答案,因为它也可以在 bar 命名空间更改名称时起作用。
  • 那么在这种情况下,您要么必须拼出类型,要么写 inline void outerFoo(A& a) { foo(a); }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-03-02
  • 2012-06-24
  • 2012-02-23
  • 2021-02-26
  • 2012-03-06
  • 2011-08-16
  • 1970-01-01
相关资源
最近更新 更多