C++ 如何为std::array声明全局编译时常量?

C++ 如何为std::array声明全局编译时常量?,c++,arrays,C++,Arrays,我正在尝试实现一个全局变量,该变量将能够由不同的文件使用,并同时与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 我的代码目前分为以下文件: main.cpp globals.h 我知

我正在尝试实现一个全局变量,该变量将能够由不同的文件使用,并同时与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
我的代码目前分为以下文件:

main.cpp globals.h 我知道通过删除extern,在globals.h中声明值

#ifndef CONSTANTS_H
#define CONSTANTS_H

namespace constants {
    const int WIDTH = 800;
    const int HEIGHT = 600;
}

#endif
并删除main.cpp中的相关行,则程序可以编译

虽然这对于较小的程序来说很简单,但每次globals.h被包含到不同的代码文件中时,这些变量都会被复制到包含代码文件中。因此,如果globals.h包含在20个不同的代码文件中,那么这些变量中的每一个都会被复制20次。标题保护不会阻止这种情况的发生,因为它们只会防止一个标题被多次包含到一个包含文件中,而不会一次包含到多个不同的代码文件中。变量的这种重复实际上不是什么大问题,因为常量不太可能很大,但是更改单个常量值还需要重新编译包含常量头的每个文件,这可能会导致大型项目的重建时间过长


这个场景的解决方法是什么?

您可以将常量定义为静态constepr成员

像这样使用它们

std::array<int, constants::height> arr;
由于运算符std::ostream&,something const&通过引用写入对象。您可以通过在源文件中的某个位置提供定义或通过避免此类使用来避免这种情况,例如

std::cout << int(constants::width) << std::endl;

将每个常量放在一个单独的头文件中。你能使用C++17吗?如果是,则在标头中将它们声明为inline constexprfile@melpomene我不确定我是否理解。NathanOliver,我主要在寻找一种有意义的C++11方法,因为我还在学习。一些C++17的东西很难理解为什么/何时工作;在width.h:namespace常量{const int width=800;}在height.h:namespace常量{const int height=600;}现在如果更改constants::width的值,只需要重新编译包含width.h的文件。这正是大段落中描述的问题,不是吗?我感谢您的时间和努力。尽管如此,如果我将该代码放在globals.h中,并将其包含在multiple.cpp中,那么每次头文件更改时,都必须重新编译所有这些代码,正如大段落中描述的问题一样。另外,在我的extern方法中,多个定义混淆了链接器是不正确的,因为这样可以很好地编译。问题是std::array需要一个编译时常量,而宽度和高度仅在定义为“main.cpp”的文件中才是编译时常量。最后,不能在诸如operator@Tetix. 我提出的解决方案是用于此Popupe的标准技术,包括C++标准库本身,例如其成员常量。odr使用的问题可以通过在某个地方提供定义来解决,这不是问题。更改globals.h中常量的值基本上会导致重新编译项目的每个文件。没有办法解决这个问题,例如并行使用.cpp?
#ifndef CONSTANTS_H
#define CONSTANTS_H

namespace constants {
    extern const int WIDTH;
    extern const int HEIGHT;
}

#endif
#ifndef CONSTANTS_H
#define CONSTANTS_H

namespace constants {
    const int WIDTH = 800;
    const int HEIGHT = 600;
}

#endif
// in some header file:
struct constants {
    constexpr static int width  = 800;
    constexpr static int height = 600;
};
std::array<int, constants::height> arr;
std::cout << constants::width << std::endl;
std::cout << int(constants::width) << std::endl;