【问题标题】:Namespace method cannot be called命名空间方法不能被调用
【发布时间】:2021-02-11 06:20:02
【问题描述】:

我无法从 File2 中的 File1 访问方法,消息是“尚未声明”。

文件 1.cpp

namespace n1 
{
    namespace 
    {
        bool method(int x)
        {
            return x;
        }
    }
}

文件2.cpp

#include <File1.cpp>
namespace n1
{
    TEST_F(Test, shouldReturnTrue)
    {
        Expect_True(method(101));
    }
}

【问题讨论】:

  • 匿名命名空间中的对象只能从同一个文件中访问。
  • 这几乎是匿名命名空间的重点
  • 好的,非常感谢。
  • @Nagy Klara 您必须将第一个文件包含在第二个文件中。否则第一个文件中的声明在第二个文件中不可见。
  • 它包含在第二个文件中。

标签: c++ namespaces googlemock name-lookup


【解决方案1】:

我无法从 File2 中的 File1 访问方法

确实如此。一个翻译单元不知道其他翻译单元中的声明。由于您在 File2.cpp 中调用函数,因此必须在该翻译单元中声明该函数。

该问题的解决方案:在使用声明的文件中声明函数:

// File2.cpp
namespace n1 
{
    namespace 
    {
        bool method(); // see next paragraph
    }
}

现在,我们遇到了另一个问题。匿名命名空间中的函数是隐式静态的。静态函数必须在所有使用 ODR 的翻译单元中定义。因此,声明毕竟是不够的。我们需要定义:

// File2.cpp
namespace n1 
{
    namespace 
    {
        bool method()
        {
        } // see addendum
    }
}

现在,由于 File1.cpp 中的函数从未被调用,并且文件中没有其他内容,我们实际上可以删除该文件。


附:函数定义具有未定义的行为,因为它不存在通过返回值(也不是通过抛出)的函数,尽管返回类型是非 void。

【讨论】:

  • OP 写了#include &lt;File1.cpp&gt;
  • @AsteroidsWithWings 更改后问题不再重现。然而,这是一个不好的问题解决方案,因为 cpp 文件不应该被包含在内。
  • 确实如此。但是,根据您发布问题前 15 分钟内的状态,它确实使您的答案不正确;)
  • @AsteroidsWithWings 在我看来,最初的问题很好,值得回答。新问题不正确,没有答案,因为问题不存在。
  • ?‍♂️ ?‍♂️ ?‍♂️
【解决方案2】:

您必须将第一个头文件包含到第二个头文件中。否则第一个头文件中的声明在第二个头文件中是不可见的。

或者您可以在使用TEST_F 的编译单元中包含这两个头文件。

或者您可以将两个文件中的依赖声明加入一个头文件中。

在您更新将文件命名为 cpp 文件的代码后,问题是您将 cpp 文件一个一个包含到另一个文件中。并且在某些编译单元中,来自一个 cpp 文件的声明在另一个 cpp 文件中不可见。或者问题可能是两个文件递归地相互包含。

您应该将两个 cpp 文件中的声明移到我上面写的头文件中。不要将通用声明放在 cpp 文件中。

【讨论】:

  • 问题是匿名命名空间。
  • @Eugene 你错了。问题是 file2 对 file1 中的声明一无所知。
  • OP 没有给我们足够的信息。我假设文件 1 不是标题,因为它包含 method() 的主体,而不仅仅是原型。此外,匿名命名空间在标头中也不好。
  • @Eugene 函数方法有内部链接。所以可以用body来声明。
  • @Eugene 问题是某些编译单元看不到file1中的声明,而是引用了方法。
猜你喜欢
  • 2013-01-19
  • 1970-01-01
  • 1970-01-01
  • 2013-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-05
  • 2014-07-07
相关资源
最近更新 更多