std::array 中使用的 C++ 11 中的全局常量

Posted

技术标签:

【中文标题】std::array 中使用的 C++ 11 中的全局常量【英文标题】:Global constant in C++ 11 used in std::array 【发布时间】:2016-09-27 18:30:47 【问题描述】:

基本上我想在另一个文件的 std::array 中使用全局常量。

我知道这个全局变量问题已经在这里被问过很多次了。例如,这个: Defining global constant in C++

而且我个人更喜欢使用方法 5 或 6:

5: 常量 int GLOBAL_CONST_VAR = 0xFF;

6: 外部常量 int GLOBAL_CONST_VAR;并在一个源文件中 const int GLOBAL_CONST_VAR = 0xFF;

我的项目需要很多常数,比如太阳常数。还有一些用于std::array,例如nvegetation_type、nrock_type。

我曾经使用方法5,所以所有其他源文件只使用一个头文件。但是多重定义问题的出现类似于: Multiple definition and header-only libraries 和这里: Why aren't my include guards preventing recursive inclusion and multiple symbol definitions?

但这在我的 Visual Studio C++ 项目中似乎不是问题,我还不知道为什么。我在Linux下使用了makefile,它也被编译了。

但是,当我使用方法 6 并在 C++11 的其他源头文件中定义数组时

extern const int nvegetation_type ;
const std::array< double, nvegetation_type > some_variable
 =   0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 
       0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1 ;

我会收到如下错误:

 error C2065: 'nvegetation_type': undeclared identifier.

我假设当我使用 header/source 方法时,我不能直接交叉引用全局变量,至少对于 std::array。 我阅读了一些类似的链接,但没有人提到这一点(也许我的搜索不走运)。 http://www.learncpp.com/cpp-tutorial/42-global-variables/ 那么解决办法是什么?

【问题讨论】:

我不知道你在问什么。 我原以为这个错误会是“未定义的标识符”而不是“未声明的标识符”? 这似乎是一个奇怪的诊断(即使问题不是链接,所以你建议的替代方案不太正确) 【参考方案1】:

extern const int nvegetation_type;

您对编译器说,在某处定义了一个常量编译器不知道编译阶段的值。

并且编译器必须知道常量的确切值,在编译阶段,用于以下指令

const std::array< double, nvegetation_type > some_variable 

所以错误。

一个简单的解决方案是使用一个头文件,您可以在其中声明 const 及其值。

const int nvegetation_type = <value>;

(甚至constexpr,考虑到您已将问题标记为c++11)并将其包含在需要的每个cpp/h文件中。

缺点是,如果你在很多cpp文件中包含这个头文件,你的程序会定义很多nvegetation_type常量;都具有相同的价值,但有很多副本。

在这种情况下,您可以在标题中添加extern

extern const int nvegetation_type = <value>;

并且,仅在一个 cpp 文件中,添加

const int nvegetation_type;

【讨论】:

那有什么办法呢? @ChangLiao - 回答改进 谢谢,这个解释很清楚。但是,当我测试最后一部分时,事实证明,在这种情况下,您可以在标头中添加 extern extern const int nvegetation_type = ;并且,仅在一个 cpp 文件中,添加 const int nvegetation_type;会导致多重定义问题,所以我删除了 .cpp 文件并且它起作用了。 @max66【参考方案2】:

感谢所有 cmets 和答案。我想我已经在你的帮助下解决了这个问题。

请原谅我一开始没有提供足够的细节。我没有对遇到的问题进行更简单的演示。通常我会创建一个测试项目。

所以最终的解决方案是混合解决方案。 如上所述, std::array 需要在编译阶段知道常量值。我的帖子中提到的方法5是理想的解决方案。在这种情况下,只需要一个头文件。它将在 std::array 中使用。这种方法的缺点是它会创建头文件的多个副本。

对于其他全局变量,可以使用方法6定义,经典头文件和源文件。

所以我把全局变量分为两类,分别用方法5和6来定义。它奏效了!

【讨论】:

以上是关于std::array 中使用的 C++ 11 中的全局常量的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 中比较 std::array ?

如何在 C++ 中使用数组?

c++新特性11 stdarray

c++中的矩阵和向量模板类

如何在 C++ 中使用数组?

如何在 C++ 中使用数组?