我有一个头文件,其中包含了我正在制作的DLL中所需的所有常量值,例如:
// myHelpers.hpp
const int kMaxNumVoices = 16;
const int kMaxBeats = 32;
....
等等。一旦我在每个.cpp上都包含.hpp,我就可以在std::array定义中使用这些常量。
问题(理论上(是,这将违反ODR,因为每个编译单元上都会使用每个var的副本(即使它们是const(,对吧?
这可以接受吗?或者可以处理一些未定义的行为?如果不可接受,正确的做法是什么?
特别是当您打算将这些常量用作非类型模板参数时(如在std::array
中(,最好的方法是将它们限定为constexpr
。
constexpr int kMaxNumVoices = 16;
constexpr int kMaxBeats = 32;
然而,为了不违反ODR,您必须不使用ODR(例如,获取它的地址,请参阅此线程了解更多信息(。这基本上与适用于const
限定变量的限制相同。
一旦您可以将代码库迁移到C++17,请另外将其标记为inline
:
constexpr inline int kMaxNumVoices = 16;
constexpr inline int kMaxBeats = 32;
我认为像log2
这样的常量应该总是由文字定义。。。
但是无论如何,您可以在C++17之后使用inline
变量,如果在C++11中,您可以使用未命名的名称空间:
namespace{
int const kMaxNumVoices = 16;
}
这意味着这些常数是CCD_ 7。
但是inline
变量只适用于每个单独的翻译单元,所以不要试图修改它们,让其他翻译单元中的代码来观察它。