使用新的C++ 11标准,我应该何时使用关键字constexpr
关键字inline
? constexpr
关键字是否提供了比inline
更多的优化,还是仅仅声称必须在编译时计算?inline vs. constexpr?
为什么constexpr
在呼叫不固定的某些情况下在GCC上工作,例如在非constexpr
变量上调用foo(x)
?这是GCC中的错误还是它实际上是标准的一部分?
使用新的C++ 11标准,我应该何时使用关键字constexpr
关键字inline
? constexpr
关键字是否提供了比inline
更多的优化,还是仅仅声称必须在编译时计算?inline vs. constexpr?
为什么constexpr
在呼叫不固定的某些情况下在GCC上工作,例如在非constexpr
变量上调用foo(x)
?这是GCC中的错误还是它实际上是标准的一部分?
断言在编译时可以计算出一些东西是是一种非常强大的优化。
内联只是通过将函数体复制/粘贴到调用站点来删除函数调用。函数体仍然需要执行,你只需要保存函数调用的开销。
但是,如果您在编译时对相同的代码进行评估,那么在运行时它是免费。
但是inline
和constexpr
都不是主要是关于优化。 inline
的主要目的是抑制一个定义规则,以便可以在头文件中定义函数(这对模板有用,而且顺便也使内联优化更容易)
而constexpr
是因为它在元编程中很有用,顺便说一句,它可以帮助编译器更好地优化代码,将更多的计算转移到编译时。
引述维基百科:
的C++ 0x将介绍关键字constexpr,其允许用户 保证的功能或对象的构造是一个编译时 常数。
标记函数内联,如果他们超短。如果编译时需要结果,则标记函数为constexpr。 (模板参数或数组大小)。如果需要,我相信一个函数可以是两个。
可以使用 非constexpr参数调用常量表达式函数或构造函数。正如一个constexpr整数文字可以被分配给一个非constexpr变量的 ,一个constexpr函数 也可以用非constexpr参数调用,并且结果存储在 非constexpr变量中。当表达式的所有成员都是 constexpr时,关键字只允许编译时恒定性的可能性 。
因此,海湾合作委员会在这不是不正确的。
虽然inline
对编译器说“这个函数在这个翻译单元的某个地方使用,并没有公开给其他目标文件”,但编译器很可能会将函数主体插入到调用者中。 constexpr
函数对编译器说:“这个函数没有副作用,也不依赖于除参数本身之外的前提条件。“
constexpr
变量只是说”这个变量不会改变,它的数据可以包含在代码中“但是它会影响你在一个静态或非静态函数中定义一个constexpr变量,例如,如果一个constexpr
阵列是非静态,GCC只是使用硬编码mov
-instructions将数据移动到堆栈,而只是static constexpr
存储在.text
-section的数据。
分配给一个变量Lambda表达式,而不捕获可能比捕获constexpr其他,因为没有他们不需要记忆来保存捕捉,并且他们的工作像一个空载的类,超载operator()
(但它们甚至可以被转换为普通函数p带有简单的一元加号:+[]{}
)。
'inline'并不意味着内部链接,因为您似乎在第一段中说过 –
根据[这个问题](http://stackoverflow.com/q/7065200/636019),当'constexpr'函数没有用在需要常量表达式的上下文中时,编译器没有义务计算表达式在编译时。 – ildjarn
但它仍指定计算*可以在编译时执行。与'inline'一样,它并不是真正的优化,但它可以提供编译器可以用来优化的其他信息。 – jalf
对,我只是在挑剔使用“must”这个词。 : - ] – ildjarn