【问题标题】:Too few arguments in function call while trying to call function with the same name from another namespace尝试从另一个命名空间调用具有相同名称的函数时,函数调用中的参数太少
【发布时间】:2019-12-01 00:07:48
【问题描述】:

我在尝试从另一个命名空间调用函数时遇到“函数调用中的参数太少”,而该命名空间恰好与调用它的函数同名。在这里,你可以明白我的意思:

namespace doa::texture {
   using namespace internal::texture;

      Texture* const CreateTexture(const std::string& name, const std::string& pathToTextureImage) {
         //below should call internal::texture::CreateTexture, not doa::texture::CreateTexture
         Texture* texture{ CreateTexture(pathToTextureImage) };
         ... //implementation detail
      }
}

namespace internal::texture {

   Texture* const CreateTexture(const std::string& pathToTextureImage) { ... }
}

我可以通过在函数调用前添加internal::texture 来轻松修复错误,但由于我使用的是using namespace internal::texture 指令,编译器应该能够识别它。

我还可以将CreateTexture 函数从命名空间internal::texture 移动到doa::texture。但我想避免这种情况。

如何在不移动函数或将internal::texture 放在调用前面的情况下解决此问题,以及为什么会发生这种情况?这只是一个函数重载的情况,为什么命名空间会导致这样的事情发生呢?谢谢。

附:这些函数在单独的文件中定义。像这样:

//irrelevant implementation details are left out
namespace doa::texture {

   Texture* const CreateTexture(const std::string& name, const std::string& pathToTextureImage);
}

namespace internal::texture {

   Texture* const CreateTexture(const std::string& pathToTextureImage);
}

【问题讨论】:

  • @ChrisMM 实际上,它在头文件中。让我编辑问题以使其清楚。
  • 您的代码受到名称隐藏的影响。在dao::texture::CreateTexture() 内,当您使用名称CreateTexture 时。全名 dao::texture::CreateTexture 对其他命名空间隐藏了名为 CreateTexture 的事物。 using namespace internal::texture 不会改变这一点。这意味着,在dao::texture::CreateTexture() 内,您仍然需要提供internal::texture::CreateTexture 的全名才能使用它。
  • 感谢您澄清@Peter。我在调用该函数之前打了一个internal::texture,因为我不想更改它的名称。其他可能的修复包括更改函数的名称或将函数移动到doa::texture。他们都工作。顺便说一句,您可以编辑您的评论以将daos 修复为doas,Doğa 是我的真实姓名,我将其用作命名空间名称。

标签: c++ visual-c++ namespaces


【解决方案1】:

我将尝试将 C++17 标准(草案)的几部分放在一起,希望我不会误解它:)

来自非限定名称查找:

1 在 6.4.1 中列出的所有情况下,按照每个相应类别中列出的顺序在范围内搜索声明;一旦找到名称的声明,名称查找就会结束。如果没有找到声明,则程序格式错误。

2 来自 using 指令指定的命名空间的声明在包含 using 指令的命名空间中变得可见;见 10.3.4。出于 6.4.1 中描述的非限定名称查找规则的目的,来自 using 指令指定的命名空间的声明被视为该封闭命名空间的成员。

使用指令

2 using-directive 指定指定命名空间中的名称可以在 using-directive 出现在 using-directive 之后的范围内使用。在非限定名称查找(6.4.1)期间,名称看起来好像它们是在最近的封闭命名空间中声明的,其中包含使用指令和指定命名空间。 [注:在此上下文中,“包含”是指“直接或间接包含”。 ——尾注]

从名字隐藏

1 名称可以通过在嵌套声明区域或派生类 (13.2) 中显式声明相同名称来隐藏。

具体来说,对于最后一部分,我相信这意味着doa::texture 中的CreateTexture 函数隐藏了internal::texture 中的CreateTexture,即使它位于不同的命名空间中。基本上,编译器在doa::texture 命名空间中看到CreateTexture,然后停止查找,因此忽略了来自internal::texture 的那个

【讨论】:

  • “在非限定名称查找 (6.4.1) 期间,名称看起来好像它们是在最近的封闭命名空间中声明的”我相信这意味着,使用 using 指令与移动相同该函数一起添加到doa::texture 命名空间。如果是这种情况,一切都应该运行良好,因为在这种情况下程序实际上可以编译并运行,doa::texture::CreateTexture 不会隐藏internal::texture::CreateTexture。现在我更加困惑了:D。
  • 我认为来自Name Hiding 的部分优先并结束查找。抱歉,我修正了错字——我经常使用名为 dao 的命名空间
  • 嗯,在这种情况下,C++ 并不关心函数在查找名称声明时所采用的参数。我得出这个结论是因为更改头文件中的声明顺序没有任何作用。我认为解决此问题的唯一方法是在函数调用前键入internal::texture。谢谢你现在我知道原因了:) P.S. dao 代表数据访问对象,还是别的什么?
  • C++ 关心参数,但是一旦在封闭范围内声明了同名的东西,它就会优先并隐藏上面的那些。在此处查看简化示例:godbolt.org/z/b3Uz4s DAO 是数据访问对象,用于 DB 工作。
  • 我看了你给出的例子。点了,谢谢你的时间@ChrisMM :)。
猜你喜欢
  • 2018-01-16
  • 2021-12-23
  • 1970-01-01
  • 2017-10-24
  • 1970-01-01
  • 1970-01-01
  • 2011-01-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多