C++ 我们应该尽可能地使用constexpr吗?
显然,我们不可能让一切都C++ 我们应该尽可能地使用constexpr吗?,c++,constexpr,c++11,C++,Constexpr,C++11,显然,我们不可能让一切都constexpr。如果我们不做任何constexpr,那么就不会有什么大问题了。到目前为止,很多代码都是在没有它的情况下编写的 但是,在任何可能拥有它的东西上打上constexpr是一个好主意吗?这有什么潜在的问题吗?为什么我不费心尝试在每个机会都以列表的形式列出constexpr,并且没有特定的顺序: 我不经常写一行函数 当我编写一个单行程序时,它通常会委托给一个非constexpr函数(例如,std::get最近出现过好几次) 它们操作的类型并不总是文字类型;是的
constexpr
。如果我们不做任何constexpr
,那么就不会有什么大问题了。到目前为止,很多代码都是在没有它的情况下编写的
但是,在任何可能拥有它的东西上打上constexpr是一个好主意吗?这有什么潜在的问题吗?为什么我不费心尝试在每个机会都以列表的形式列出
constexpr
,并且没有特定的顺序:
- 我不经常写一行函数
- 当我编写一个单行程序时,它通常会委托给一个非constexpr函数(例如,
最近出现过好几次)std::get
- 它们操作的类型并不总是文字类型;是的,引用是文本类型,但是如果引用的类型本身不是文本,那么在编译时我就不能有任何实例
- 它们返回的类型并不总是文本
- 就语义而言,它们在编译时并不都有用,甚至没有意义
- 我喜欢将实现和声明分开
对于
constexpr
构造函数,我没有什么特别的意见或建议,因为我不确定自己是否能完全理解它们,而且用户定义的文本还不可用。编译器不会为此烦恼。当/如果您在不符合constexpr
要求的代码上使用编译器时,编译器将(或无论如何都应该)为您提供诊断
同时,我也会有点犹豫,因为你可以。即使它不会/不会打扰编译器,您的主要读者还是阅读代码的其他人。至少在我看来,你应该使用constexpr
来向他们传达一个相当具体的意思,而只是把它贴在其他表达式上,因为这样做会产生误导。我认为对于读者来说,想知道标记为constexpr
但仅用作正常运行时函数的函数发生了什么是公平的
同时,如果您有一个确实希望在编译时使用的函数,而您还没有这样使用它,那么将其标记为
constexpr
可能会更有意义。是。我相信,无论你在哪里,把这样的const
ness放在任何地方都是一个很好的实践。例如,在您的类中
如果给定的方法没有修改任何成员,那么您总是倾向于在末尾添加const
关键字
除了语言方面,提到const
ness也可以很好地向未来的程序员/审阅者表明表达式在该区域内具有const ness。它涉及到良好的编码实践,也增加了可读性。e、 g.(来自@Luc)
现在放置constexpr
表明get()
也必须是constexpr
我看不到任何问题或影响,因为constexpr
编辑:在某些情况下,
constexpr
的另一个优点是可以将它们用作模板
参数。我倾向于同意Scott Meyers的这一点(对于大多数事情):“尽可能使用constexpr
”(来自有效现代C++的第15项),特别是当您提供一个API供其他人使用时。如果您希望使用函数执行编译时初始化,但却无法执行,因为库没有声明它constexpr
。此外,所有类和函数都是API的一部分,无论是供世界使用还是仅供您的团队使用。因此,尽可能地使用它,以扩大其使用范围
// Free cup of coffee to the API author, for using constexpr
// on Rect3 ctor, Point3 ctor, and Point3::operator*
constexpr Rect3 IdealSensorBounds = Rect3(Point3::Zero, MaxSensorRange * 0.8);
这就是说,
constexpr
是接口的一部分,因此如果接口不能自然地适合可以是constexpr
的东西,不要承诺它,以免以后不得不破坏API。也就是说,不要仅仅因为当前的、只有实现可以处理它而将constexpr
提交到接口。等等,那么这是编译器可以为自己派生的属性吗?那么为什么要使用关键字呢?@Nemo当您错误地声明了不符合所有要求的constexpr
时,编译器需要发出诊断。因此,关键字对于作者来说至少是有用的,可以肯定地断言声明的函数或构造函数满足这些需求。我打开了另一个问题(如果编译器可以处理的话,隐式地允许在常量上下文中不标记constexpr
。@Luc:那么这只是一个编译时断言?似乎他们可以在不窃取整个关键字的情况下实现这一点。但是好的。@Nemo这就像要求数组的大小是一个常量表达式一样。编译器可以“计算”出inti=1;字符数组[i]代码>很好,但我们不允许。(实际上这是一个糟糕的例子,因为const int i=expr;
完全代表了您所建议的数组声明仅在某些情况下是正确的;)是的,编译器可以自行派生它。我似乎记得一些讨论建议应该这样做,但目前找不到。在任何情况下,这都没有成为标准,所以这没有多大关系。constepr
在应用于函数时与不变性完全正交,请考虑:constepr int&f(int&i){return i;}
,将其用作++f(some_int)
<代码>constexpr int i然而,code>确实是不可变的。
// Free cup of coffee to the API author, for using constexpr
// on Rect3 ctor, Point3 ctor, and Point3::operator*
constexpr Rect3 IdealSensorBounds = Rect3(Point3::Zero, MaxSensorRange * 0.8);