【问题标题】:C++: Using external linkage with an unnamed namespace to use a constant variableC++:使用带有未命名命名空间的外部链接来使用常量变量
【发布时间】:2019-03-09 01:42:16
【问题描述】:

我的目标是当我从 main 中调用 myFunction 时,我不必传递 SIZE 常量。然后应该运行 myFunction.cpp 中的函数并简单地输出数组的内容。

我已经阅读了一些关于外部链接的注释,但我觉得我对它的理解还不够好,无法在这种情况下应用任何内容。理想情况下,main.cpp 不应该做太多的改变,除非在绝对必要的情况下给包括 SIZE 在内的命名空间命名。

ma​​in.cpp

#include <iostream>
#include "myFunction.hpp"

namespace
{
    extern const int SIZE = 10;
}

void myFunction(char []);

int main()
{
    char myArray[SIZE] = "123456789";

    myFunction(myArray);
}

myFunction.h

#ifndef MYFUNCTION_H_INCLUDED
#define MYFUNCTION_H_INCLUDED

namespace
{
    extern const int SIZE;
}

#endif // MYFUNCTION_H_INCLUDED

myFunction.cpp

#include <iostream>

void myFunction(char myArray[])
{
    for(int i = 0; i < SIZE; ++i)
    {
        std::cout << myArray[i] << " ";
    }
}

到目前为止,我仍然收到未在该范围内声明 SIZE 的错误 (myFunction.cpp)。

问题:我必须做些什么才能使这个示例有效?如果可能的话,我还想解释一下为什么会以这种方式处理共享 SIZE。

【问题讨论】:

  • 根据定义,匿名命名空间对于翻译单元始终是本地/私有的,这意味着在匿名命名空间中声明的内容可访问在同一个源模块中。通过在匿名命名空间中声明 extern 链接,您究竟打算完成什么?您希望它如何工作?
  • main.cpp 是作为驱动程序预先构建的。正如我所说,我的目标是让位于该匿名命名空间内的常量 SIZE 可在 myFunction.cpp 中使用,而无需实际传递它。
  • 我不知道“main.cpp 被预先构建为驱动程序”是什么意思。再说一遍:匿名命名空间,顾名思义,就是匿名的。它只能在 same 翻译单元中使用和引用。在翻译单元的匿名命名空间中声明的对象不能从任何其他翻译单元获得。您的第二个 .cpp 文件只是在它自己的、单独的、匿名的命名空间中声明了一个 SIZE,它本身不能从任何其他翻译单元访问。不幸的是,您声明的目标在 C++ 中是不可能的。 C++ 不能以这种方式工作。
  • 我的意思是 main.cpp 是作为练习的一部分提供给我的——“注意你正在将 myArray 传递给函数。还要注意我们下面有全局命名空间。数组位置的数量used 在一个恰当地命名为 SIZE 的常量中找到。这样做的目的是——我们不会将 SIZE 作为参数传递。相反,我们将尝试通过使用下面定义的外部链接来共享这个 SIZE 常量(在未命名的命名空间中). 试着让它工作。如果有帮助,你可以给持有 SIZE 的未命名命名空间起一个名字" -- 说明暗示这是可能的,不是吗?
  • 这些说明要么不完整,要么错误,要么不需要使用多个翻译单元。

标签: c++ namespaces external linkage


【解决方案1】:

未命名的命名空间告诉编译器内部的任何内容都不会与另一个翻译单元共享。 (也就是说,里面的所有东西都有内部链接。)只要SIZE在一个未命名的命名空间中,它就不能有外部链接,所以myFunction()看不到

如果可能的话,我也很想解释一下为什么人们会以这种方式处理共享 SIZE。

由于您正在做一个玩具练习,我猜想人们会以这种方式处理共享SIZE,以更好地了解内部和外部联系。这是一个练习,而不是一个真实的例子。

举一个更现实的例子,也许版本字符串既简单又好?您的应用程序可能有一个版本(例如“1.69.8109”),它会在不同点显示。该版本可以声明为const string,供多个源文件使用。它将进入(命名的)命名空间以避免名称冲突。它可以在源文件而不是头文件中定义,以限制版本更改时所需的重新编译量。 (只有具有定义的源需要重新编译,而不是每个使用版本字符串的源。)这可能是一个合理的好处,特别是如果版本号经常合理地更改,不一定只是在准备新版本时。

(来自 cmets):“试着让它工作。如果有帮助,你可以给持有 SIZE 的未命名命名空间命名”

有趣的是,练习说明会多久告诉你该做什么。 (呵呵,“如果”。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-08
    • 2012-08-26
    • 2015-05-13
    • 1970-01-01
    相关资源
    最近更新 更多