什么时候应该在 C 11 中使用 constexpr 功能?

新手上路,请多包涵

在我看来,拥有一个“总是返回 5 的函数”正在破坏或淡化“调用函数”的含义。必须有一个原因,或者需要这种能力,否则它不会出现在 C++11 中。为什么会在那里?

 // preprocessor.
#define MEANING_OF_LIFE 42

// constants:
const int MeaningOfLife = 42;

// constexpr-function:
constexpr int MeaningOfLife () { return 42; }

在我看来,如果我编写了一个返回文字值的函数,并且我进行了代码审查,那么有人会告诉我,我应该声明一个常量值而不是写 return 5。

原文由 Warren P 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 761
2 个回答

假设它做了一些更复杂的事情。

 constexpr int MeaningOfLife ( int a, int b ) { return a * b; }

const int meaningOfLife = MeaningOfLife( 6, 7 );

现在,您可以将某些东西评估为常数,同时保持良好的可读性,并允许比仅将常数设置为数字稍微复杂一些的处理。

它基本上为可维护性提供了很好的帮助,因为它变得更加明显你在做什么。以 max( a, b ) 为例:

 template< typename Type > constexpr Type max( Type a, Type b ) { return a < b ? b : a; }

这是一个非常简单的选择,但这确实意味着如果您调用 max 具有常量值,它会在编译时而不是在运行时显式计算。

另一个很好的例子是 DegreesToRadians 函数。每个人都发现度数比弧度更容易阅读。虽然您可能知道 180 度是 3.14159265 (Pi) 的弧度,但更清晰的写法如下:

 const float oneeighty = DegreesToRadians( 180.0f );

这里有很多好信息:

http://en.cppreference.com/w/cpp/language/constexpr

原文由 Goz 发布,翻译遵循 CC BY-SA 4.0 许可协议

这里的很多回复似乎有点倒退,和/或说安静的部分响亮而响亮的部分安静。关于 constexpr 要了解的一件事是:

 // This guarantees only that the value of "MeaningOfLife" can not be changed
// from the value calculated on this line by "complex_initialization()"
// (unless you cast away the const of course, don't do that).
// Critically here, everything happens at *runtime*.
const int MeaningOfLife = complex_initialization(1234, 5678, "hello");

 // This guarantees that "MeaningOfLife" is fully evaluated and "initialized"
// *at compile time*.  If that is not possible due to complex_initialization()
// not being evaluatable at compile time, the compiler is required to abort
// compilation of the program.
// Critically here, to put a fine point on it, everything happens at
// *compile time*, guaranteed.  There won't be a runtime call to
// complex_initialization() at all in the final program.
constexpr int MeaningOfLife = complex_initialization(1234, 5678, "hello");

请注意,正是 左侧constexpr 强制保证提供 constexpr 它存在的理由。当然,确保 右侧 实际上可以在编译时进行评估取决于您,重要的是,仅声明一个函数 constexpr 本身并不会这样做。

因此,您的问题的 constexpr 是,当您需要或希望其初始化( 右侧 发生的一切)被迫完全在编译时发生或破坏建造。

原文由 Gary R. Van Sickle 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题