【问题标题】:Calling a function overloaded in several namespaces from inside one namespace从一个命名空间内调用在多个命名空间中重载的函数
【发布时间】:2011-05-25 05:00:41
【问题描述】:

我有以下代码sn-p:

void foo(double a) {}

namespace bar_space
{
  struct Bar {};

  void foo(Bar a) {}
}

foo(double) 是库中的通用函数。 我有自己的命名空间 bar_space 和自己的结构 Bar。我想为 Bar 实现 foo() 的重载,从而使 Bar 更类似于内置类型。

当我尝试从命名空间中调用原始 foo(double) 时出现问题:

namespace bar_space
{
  void baz()
  {
    foo(5.0); // error: conversion from ‘double’ to non-scalar type ‘ssc::bar_space::Bar’ requested
  }
}

这在我的 Fedora 和 Mac 上都无法在 gcc 上编译。

打电话

foo(5.0)

来自命名空间之外或使用

namespace bar_space
{
  ::foo(5.0)
}

工作正常,但这并没有使我的新功能像我希望的那样好(其他开发人员也在 bar_space 中工作)。

bar_space 是否隐藏了原来的功能?有没有办法让 foo(5.0) 可以在 bar_space 内调用而无需显式范围 (::)?任何帮助表示赞赏。

【问题讨论】:

  • 我是 C++ 的新手,但你能用 using bar_space::foo; 这样的东西吗?
  • 这将有助于在 bar_space 之外使用 foo(Bar),但不会让 foo(double) 进入 bar_space。
  • 类似的东西是可能的:codepad.org/0IcNXZb6

标签: c++ overloading


【解决方案1】:

在 C++ 中,有一个名为name hiding 的概念。基本上,如果嵌套范围内有同名的函数/类,则函数或类名是“隐藏的”。这可以防止编译器“看到”隐藏的名称。

C++ 标准第 3.3.7 节内容如下:

名称可以通过显式隐藏 在 a 中声明同名 嵌套声明区域或派生 类(10.2)

所以,回答您的问题:在您的示例中,void foo(double a);void bar_space::foo(Bar a);隐藏 所以您需要使用:: 范围运算符来调用外部函数。

【讨论】:

  • 没有 bar_space::foo(double)
  • 标准已经说了。感谢您的澄清。
  • 这里缺少的一点是 name-mangling 是在 name-hiding 之后应用的。如果反过来,该代码将按(错误地)预期工作。
【解决方案2】:

但是,在您的示例代码中,您可以使用类似的东西

namespace bar_space 
{
    using ::foo;
    void baz()
    {
       Bar bar;
       foo(5.0);
       foo(bar);
    }
}

【讨论】:

  • 我打算发布这个答案并对其进行了测试,它对我来说编译得很好。 (我也因工作会议等而分心)。
【解决方案3】:

是的,bar_space 隐藏了原始函数,不,如果没有明确的作用域 if foo(double) 是在全局命名空间中定义的,则不能从 bar_space 中调用 foo(5.0)。

【讨论】:

  • 好吧,那我就用 ::。我没提,但是foo()确实是math.h中的函数ceil(),所以定义在全局命名空间中。
  • @Christian - 如果您改为包含 <cmath>(无论如何您都应该这样做),那么 ceil 将包含在 std 命名空间中,在这种情况下您的问题就会消失。
  • 我刚做了。问题消失了。是的,我应该一直使用 ...
猜你喜欢
  • 1970-01-01
  • 2016-03-20
  • 2017-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-06
相关资源
最近更新 更多