如何为 std::array 声明全局编译时常量?
How can I declare a global compile-time constant for std::array?
>我正在尝试实现一个全局变量,该变量将被不同的文件使用,同时与std::array一起使用,但是我收到以下编译器错误:
error: the value of ‘constants::HEIGHT’ is not usable in a constant expression
note: ‘constants::HEIGHT’ was not initialized with a constant expression
我的代码目前被拆分为以下文件:
主.cpp
#include <iostream>
#include "classA.h"
#include "globals.h"
namespace constants {
extern const int WIDTH = 800;
extern const int HEIGHT = 600;
}
int main()
{
ClassA classA;
printf("Hello World");
std::cout << constants::WIDTH << " " << constants::HEIGHT << std::endl;
return 0;
}
类A.h
#include <array>
#include "globals.h"
class ClassA {
public:
std::array<int, constants::HEIGHT> m_arrayFixedRGBA;
ClassA();
};
A类.cpp
#include "classA.h"
ClassA::ClassA() {
}
全局.h
#ifndef CONSTANTS_H
#define CONSTANTS_H
namespace constants {
extern const int WIDTH;
extern const int HEIGHT;
}
#endif
我知道通过删除extern
,像这样声明globals.h
值
#ifndef CONSTANTS_H
#define CONSTANTS_H
namespace constants {
const int WIDTH = 800;
const int HEIGHT = 600;
}
#endif
并删除main.cpp
中的相关行,然后程序就可以编译了。
虽然这很简单(对于较小的程序来说很好),但每次globals.h
#included 到不同的代码文件中时,这些变量中的每一个都会复制到包含代码文件中。因此,如果globals.h
被包含在 20 个不同的代码文件中,则每个变量都会重复 20 次。标头保护不会阻止这种情况的发生,因为它们只会防止标头多次包含在单个包含文件中,而不是一次包含在多个不同的代码文件中。这种变量的重复并不是什么大问题(因为常量不太可能很大),但是更改单个常量值还需要重新编译包含常量标头的每个文件,这可能会导致大型项目的重建时间过长。
这种情况的解决方法是什么?
您可以将常量定义为static constexpr
成员
// in some header file:
struct constants {
constexpr static int width = 800;
constexpr static int height = 600;
};
并像使用它们一样使用
std::array<int, constants::height> arr;
------编辑------
请注意,此方法仅声明这些编译时常量,但不定义任何变量。因此,多个定义混淆链接器没有问题(就像使用extern
变量的实现一样)。
但是,在 C++17 之前,可能会出现相反的问题:如果 odr 使用这些常量,则会出现链接时错误,因为链接器找不到定义。例如,以下代码将失败
std::cout << constants::width << std::endl;
因为operator(std::ostream&, something const&)
通过引用来获取要写入的对象。您可以通过在某处(在源文件中)提供定义或避免此类使用来避免这种情况,例如
std::cout << int(constants::width) << std::endl;
相关文章:
- C++常量数组的编译时间较长
- 在编译时将常量字符* 转换为常量 char_type*
- 将编译时常量向量转换为堆分配版本
- 如何在常量计算表达式中获取编译时错误?
- 如何在编译时解析静态常量 std::string?
- 有没有办法在类实例中存储编译时常量?
- 检测编译时文本和常量
- ARM C++编译器不会编译具有可变常量成员的结构
- 强制在编译时计算类的类的常量成员
- Constexpr 类采用常量引用不编译
- 为什么对数组的常量左值引用不编译在下面?
- 由于缺少常量而出现编译错误
- 为什么在将常量 ptr 分配给常量引用时没有收到编译错误?
- 为什么可以在编译时访问非常量、非静态成员而无需类的实例
- 不是 VS2017 中的编译时常量表达式
- 将编译时定义大小的数组初始化为常量表达式
- 将大小为编译时常量的数组初始化为单个值
- 如何为 std::array 声明全局编译时常量?
- 返回非常量引用编译的 Const 方法
- 常量正确性编译错误到模板函数中的无效转换错误