问题 我是否应该尽可能在C ++ 11中将'const int'替换为'constexpr int'?


你会替换吗?

const int one = 1;
const int two = 2;

有了这个?

constexpr int one = 1;
constexpr int two = 2;

我的理解是正确的,两个块在语义上是相同的,并且它目前只是一个品味的问题?

另一方面,作为 constexpr 暗示 const,你可以说,总是更喜欢限制性更强的形式,即使是在无关紧要的微不足道的情况下也更为一致?

(我知道当右侧的表达式允许更复杂时,情况会完全改变。因此,为了澄清,问题只关注表达式是固定整数的最简单的情况。)


6259
2018-02-25 23:40


起源

我唯一能想到的是,如果你指定类似API的东西,你可能决定使用它 const int 存储常量表达式,因为该属性在将来的修订版本中可能不会保留。 - Pubby


答案:


我想你的发言是这么说的 const 和 constexpr “在语义上是相同的“应该修改:它们都声明了值不能改变的对象,但是 constexpr 还要求初始化表达式在编译时可计算。

现在,如果右侧的表达式无法在编译时计算,则使用 constexpr 是不可能的。另一方面,只要初始化程序是文字,你 可以 使用 constexpr,但要考虑变量的语义是什么:你的常量变量是否真的代表了其值的东西 应该 在编译时可计算?

在SW维护/演化光学系统中,您可能会改变初始化变量的方式:今天初始化器是文字,明天它可能是更复杂的表达式。

无论您为其分配值的方式如何 现在你觉得吗? i 除了文字之外的其他任何东西都需要初始化,并且初始化表达式在编译时可能无法计算?如果是这种情况,那么只需创建变量即可 const,即使你正在用文字初始化它;否则,成功 constexpr

换句话说,选择最能表达变量语义的限定符。


13
2018-02-26 00:01



我会把最后的建议转到头上:问自己:“这个名字需要在编译时解决吗?” (例如,我在某处使用它作为数组大小或枚举值。)如果是这样,请使用 constexpr 所以没有人试图以一种会导致名称使用失败的方式改变它。 - rici
@rici:有道理,但我认为OP主要关注的是你评论中问题的答案是“否”的情况。当答案为“是”时,肯定应该做出变量 constexpr。但是,如果初始化程序不是严格需要的话,该怎么办? constexpr 表达,现在碰巧是一个?这是我试图回答的问题。 - Andy Prowl
很公平,但在我看来很难回答“可能 i 有一天需要通过比文字更复杂的东西来初始化?“,并且很容易回答问题” i 需要在编译时知道吗?“使用 constexpr 始终如一地表明后者为代码阅读器提供了有用的信息;运用 const 表明你想象一个可能的反事实未来,而不是那么多。 - rici
@rici:事情是,如果他甚至 通缉 声明 const int i = ... 然后使用它作为数组大小,他不会被允许,因为编译器会发出错误。虽然确实“始终使用constexpr来指示后者为代码阅读器提供有用的信息“,你不能选择这样做。我相信这个问题就是那些你有选择的情况。 - Andy Prowl
@PhilippClaßen你的经验法则是正确的; “根据这个规则,我会在我的例子中选择constexpr” - 在你的例子中,我们没有根据你猜测你可能希望客户端代码做什么,尽管表面上看 two = 2 改变是一种疯狂的身份。更明确地说,是您想要避免的关键场景 constexpr 是你现在硬编码一个值,但可以看到以后可能需要使用命令行或配置文件中的值,虽然有很多变化和其他scenerios .... - Tony Delroy