全局const var声明一次,有可能吗?

问题描述

我有一个文件,其中包含我正在制作的DLL中所需的所有const值,例如:

// 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使用(例如,获取其地址,有关更多信息,请参见this thread)。这基本上与应用于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;
}

这意味着这些常量为inline

但是inline变量仅适用于每个单独的翻译单元,因此请勿尝试对其进行修改并让其他翻译单元中的代码对其进行观察。