使用新的 C++11 标准,什么时候应该使用
inline
关键字而不是 constexpr
关键字? constexpr
关键字是否比 inline
提供任何额外的优化,还是仅仅断言必须在编译时计算?
为什么
constexpr
在某些调用不恒定的情况下(例如在非 foo(x)
变量上调用 constexpr
)可以在 GCC 上工作?这是 GCC 中的错误还是它实际上是标准的一部分?
断言某些东西可以在编译时计算是一种非常强大的优化。
内联仅通过将函数体复制/粘贴到调用站点来删除函数调用。函数体仍然需要执行,您只需节省函数调用的开销。
但是,如果您在编译时对相同的代码进行评估,那么它在运行时是“free”的。 但是
inline
和
constexpr
都不是主要关于优化。
inline
的主要目的是抑制单定义规则,以便可以在标头中定义函数(这对模板很有用,顺便说一句,也使内联优化更容易)之所以存在
constexpr
,是因为它在元编程中很有用,顺便说一句,它可以通过将更多计算移至编译时来帮助编译器更好地优化代码。
C++0x将引入关键字constexpr,它允许用户 保证函数或对象构造函数是编译时的 常数。
如果函数超短,则将其标记为内联。如果编译时需要结果,则将函数标记为 constexpr。 (模板参数或数组大小)。我相信如果需要的话,一个功能可以兼而有之。
可以使用以下方式调用常量表达式函数或构造函数 非 constexpr 参数。就像 constexpr 整数文字一样 分配给非 constexpr 变量,constexpr 函数也可以 使用非 constexpr 参数调用,结果存储在 非 constexpr 变量。关键字只允许可能性 当表达式的所有成员都为时,编译时恒定性 常量表达式。
所以,GCC 在这方面并没有错。
inline
对编译器说“此函数在此翻译单元中的某处使用,并且对其他目标文件不公开”,但编译器很可能将函数体插入到调用者中。
constexpr
函数对编译器说“这个函数没有副作用,并且不依赖于参数本身以外的前提条件。”constexpr
变量只是说“这个变量不会改变,它的数据可以包含在代码中。”。但是,如果您在静态或非静态函数中定义 constexpr 变量,则会有所不同,例如。如果
constexpr
数组是非静态的,gcc 只是将带有硬编码 mov
指令的数据移动到堆栈上,而 static constexpr
只是将数据存储在 .text
部分中。不带 capture 分配给变量的 Lambda 表达式可以是 constexpr,而不是带 capture,因为如果不带 capture,它们不需要内存来保存捕获,并且它们的工作方式就像具有重载的空类
operator()
(但它们甚至可以转换为普通函数指针)用一个简单的一元加号:
+[]{}
)。