constexpr是新的内联吗? P> >据我所知,C++中的内联关键字可以追溯到旧编译器,然后称为优化编译器,它既不能优化也不能优化现代编译器,因此将函数标记为内联,告诉编译器应该内联,并且因为副作用会阻止ODR问题。随着编译器越来越好,有人意识到编译器在优化方面比程序员做得好得多,因此编译器的内联需求更多地成为一个“提示”,大多数人都是这样做的?现代编译器忽视了这一点

constexpr是新的内联吗? P> >据我所知,C++中的内联关键字可以追溯到旧编译器,然后称为优化编译器,它既不能优化也不能优化现代编译器,因此将函数标记为内联,告诉编译器应该内联,并且因为副作用会阻止ODR问题。随着编译器越来越好,有人意识到编译器在优化方面比程序员做得好得多,因此编译器的内联需求更多地成为一个“提示”,大多数人都是这样做的?现代编译器忽视了这一点,c++,C++,输入c++11及其后续版本。在我看来,constexpr似乎处于类似的情况,至少在某些用途上是如此,特别是函数和变量。据我所知,它告诉编译器可以在编译时对某个函数求值。但这是编译器应该能够自行解决的问题。一旦编译器在优化方面做得更好,这个特性是否也会成为一个“提示” 注意:我不是问constexpr的其他用法,比如if语句。我知道这些是必要的 据我所知,它告诉编译器可以在编译时对某个函数求值 不是可以,而是可以。constexpr关键字不会告诉编译器允许它做什么,它可以在编译时计算它想要的任何东

输入c++11及其后续版本。在我看来,constexpr似乎处于类似的情况,至少在某些用途上是如此,特别是函数和变量。据我所知,它告诉编译器可以在编译时对某个函数求值。但这是编译器应该能够自行解决的问题。一旦编译器在优化方面做得更好,这个特性是否也会成为一个“提示”

注意:我不是问constexpr的其他用法,比如if语句。我知道这些是必要的

据我所知,它告诉编译器可以在编译时对某个函数求值

不是可以,而是可以。constexpr关键字不会告诉编译器允许它做什么,它可以在编译时计算它想要的任何东西。相反,关键字告诉编译器所需的变量或函数的质量,特别是它可以在中使用。如果程序未能达到要求,编译器将抱怨错误或警告。您会得到一条比其他情况下更相关的错误消息–编译器可以告诉您为什么您的实体不符合编译时计算条件,因为它知道您的意图是将实体作为编译时常量

例如,如果定义了const unsigned a,则如果a的值在编译时未知,则使用std::array是错误的。错误可能在a的初始化中,或者模板参数应该是b而不是a。编译器必须报告错误,因为a不是常量表达式,并让程序员进行调查。另一方面,如果a被声明为constexpr,编译器反而会抱怨a的值在编译时未知的原因,从而缩短调试时间

如果没有constexpr,下面的代码将生成一条可能较弱的错误消息

{ 常量无符号a=foo; 常数无符号b=42; std::array stuff;//错误:“a”不是常量表达式。 // ... } 将a和foo声明为constexpr后,错误消失。为什么?因为上周编写foo时,编译器被告知该函数必须在常量表达式中可用。因此,编译器指出了为什么不能在编译时对foo进行求值,您立即修复了这个bug。那是上周,而foo的实现在您的脑海中仍然是新鲜的。本周不是,在做了十几件其他事情之后,包括花了一个小时与编译器争论,因为您认为a必须是一个常量表达式,因为它是用foo初始化的

据我所知,它告诉编译器可以在编译时对某个函数求值

不是可以,而是可以。constexpr关键字不会告诉编译器允许它做什么,它可以在编译时计算它想要的任何东西。相反,关键字告诉编译器所需的变量或函数的质量,特别是它可以在中使用。如果程序未能达到要求,编译器将抱怨错误或警告。您会得到一条比其他情况下更相关的错误消息–编译器可以告诉您为什么您的实体不符合编译时计算条件,因为它知道您的意图是将实体作为编译时常量

例如,如果定义了const unsigned a,则如果a的值在编译时未知,则使用std::array是错误的。错误可能在a的初始化中,或者模板参数应该是b而不是a。编译器必须报告错误,因为a不是常量表达式,并让程序员进行调查。另一方面,如果a被声明为constexpr,编译器反而会抱怨a的值在编译时未知的原因,从而缩短调试时间

如果没有constexpr,下面的代码将生成一条可能较弱的错误消息

{ 常量无符号a=foo; 常数无符号b=42; std::array stuff;//错误:“a”不是常量表达式。 // ... } 将a和foo声明为constexpr后,错误消失。为什么?因为上周编写foo时,编译器被告知该函数必须在常量表达式中可用。因此,编译器指出了为什么不能在编译时对foo进行求值,并修复了错误r 马上。那是上周,而foo的实现在您的脑海中仍然是新鲜的。本周不是,在做了十几件其他事情之后,包括花了一个小时与编译器争论,因为您认为a必须是一个常量表达式,因为它是用foo初始化的

但这是编译器应该能够在其 拥有一旦编译器得到支持,这个特性是否也会成为一个“提示” 更擅长优化

constexpr不仅仅是一种优化——没有 因此,编译器不允许在需要常量表达式的上下文中使用函数,例如在非类型模板参数中

但我相信你已经知道很多了。真正的问题是:未来的C++标准是否允许在常量表达式上下文中使用函数,即使它没有显式地标记CONTXPRO-如果满足上下文上下文要求?

不,我认为这是C++开发的相反方向。考虑C++ 20的概念。它的一个主要目标是改进错误消息:编译器不需要遍历嵌套的模板定义,而是很早就知道模板参数不符合要求。关键字constexpr的作用是相同的:编译器不会遍历函数调用树,发现调用堆栈深处的函数在编译时无法计算,而是提前报告错误

但这是编译器应该能够在其 拥有一旦编译器得到支持,这个特性是否也会成为一个“提示” 更擅长优化

constexpr不仅仅是一种优化——没有 因此,编译器不允许在需要常量表达式的上下文中使用函数,例如在非类型模板参数中

但我相信你已经知道很多了。真正的问题是:未来的C++标准是否允许在常量表达式上下文中使用函数,即使它没有显式地标记CONTXPRO-如果满足上下文上下文要求?


不,我认为这是C++开发的相反方向。考虑C++ 20的概念。它的一个主要目标是改进错误消息:编译器不需要遍历嵌套的模板定义,而是很早就知道模板参数不符合要求。关键字constexpr服务于相同的目标:编译器不需要遍历函数调用树,发现调用堆栈深处的函数无法在编译时进行计算,尽早报告错误。

理想的编译器可能会找出哪些函数实际上是constexprand。从这个意义上讲,可以将该关键字视为对编译器的提示

但是我认为比较const和constexpr更有意义,因为它们告诉编译器和人类读者的是什么。理想的编译器还可以确定哪些变量和成员函数应该是常量。正如您可能知道的,还有其他一些很好的理由可以标记所有可能的内容。const compiler为您查找bug,更易于阅读,有助于编译器进行优化

constexpr也是如此。如果您声明了一个不能在编译时计算的变量constexpr,那么您会得到一个错误,您已经记录了该变量可以在编译时计算,这有助于编译器进行优化


还请注意,忽略constexpr对运行时性能没有意义,这对于内联来说是不正确的。

理想的编译器可能会找出哪些函数实际上是constexpr。在这种意义上,可以将该关键字视为对编译器的提示

但是我认为比较const和constexpr更有意义,因为它们告诉编译器和人类读者的是什么。理想的编译器还可以确定哪些变量和成员函数应该是常量。正如您可能知道的,还有其他一些很好的理由可以标记所有可能的内容。const compiler为您查找bug,更易于阅读,有助于编译器进行优化

constexpr也是如此。如果您声明了一个不能在编译时计算的变量constexpr,那么您会得到一个错误,您已经记录了该变量可以在编译时计算,这有助于编译器进行优化


还请注意,忽略constexpr对运行时性能没有意义,这对于内联来说是不正确的。

尽管constexpr包含一些与内联重叠的上下文,但constexpr非常有用,更重要的是,它与优化无关。@SamVarshavchik但你认为编译器不能在编译时计算所有可能的内容吗?即使是没有显式标记为constexpr的内容,也不能因此而将constexpr标记为一个提示?或者编译器无法知道某个东西是否应该标记为constexpr?我想我要问的是:即使没有显式标记,也只是让一切都成为可能的constexpr有缺点吗?不可能让一切都成为可能的constexpr,因为
并不是所有的东西都符合constexpr表达式的技术要求。它不是一个提示,而是一个请求。它告诉我们必须在编译时对某个函数求值。如果编译器无法理解如何执行该操作,则函数不符合条件数,它会引发错误。@SamVarshavchik这就是我所说的“一切可能”的意思,我想我可以改写它,说符合constexpr要求的所有内容。问题是一样的:为什么编译器不在编译时对所有内容进行计算这可能是,无需通过标记内容constexpr告诉它?尽管constexpr包含一些与inline重叠的上下文,但constexpr非常有用,更重要的是,它与优化无关。@SamVarshavchik但你认为编译器不能在编译时计算所有可能的内容吗?即使是没有显式标记为constexpr的内容,也不能因此而将constexpr标记为一个提示?或者编译器无法知道某个东西是否应该标记为constexpr?我想我要问的是:即使没有明确标记,也只让一切可能成为constexpr是否有缺点。不可能让一切可能成为constexpr,因为不是所有东西都满足成为constexpr表达式的技术要求。这不是一个暗示,而是一个请求。它告诉我们必须在编译时对某个函数求值。如果编译器无法理解如何执行该操作,则函数不符合条件数,它会引发错误。@SamVarshavchik这就是我所说的“一切可能”的意思,我想我可以改写它,说符合constexpr要求的所有内容。问题是一样的:为什么编译器不在编译时对所有内容进行计算这可能是,不必通过标记constexpr来告诉它?