Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/155.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我们应该尽可能地使用constexpr吗?_C++_Constexpr_C++11 - Fatal编程技术网

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
来向他们传达一个相当具体的意思,而只是把它贴在其他表达式上,因为这样做会产生误导。我认为对于读者来说,想知道标记为
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确实是不可变的。
// 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);