有没有constexpr应该避免的情况,即使它可以使用? [英] Are there cases where constexpr should be avoided, even it it could be used?
问题描述
如果一个对象被声明为 const
,它的值被保证只在运行时可用,但如果它被声明为 constexpr
,则该值保证在编译期间和在运行时可用。所以如果我有一个对象的值在编译期间可用,是否有任何情况下,我不应该声明它 constexpr
?
If an object is declared const
, its value is guaranteed to be available only at runtime, but if it's declared constexpr
, the value is guaranteed to be available both during compilation and at runtime. So if I have an object whose value is available during compilation, are there any situations where I should not declare it constexpr
?
const int magicValue = 42; // Does this ever make sense
// (using const instead of constexpr)?
对于函数,如果函数可以返回在编译期间计算的值, ,是否可以不声明函数 constexpr
?
For functions, if a function can return a value computed during compilation when passed arguments with values available during compilation, would it ever make sense to not declare the function constexpr
?
struct Point { int x; int y; };
Point midPoint(Point p1, Point p2) // Does this ever make
{ // sense (not declaring
return { (p1.x + p2.x) / 2 , (p1.y + p2.y) / 2 }; // the function
} // constexpr)?
我可以想到的唯一情况是当你不想提交函数当使用已知的编译时参数调用时计算编译时常数,例如,如果您想保留更改 midPoint
的灵活性,而不更改其接口(从而潜在地打断呼叫者)。例如,您可能希望保留向 midPoint
添加非 - constexpr
副作用的灵活性,例如IO 。
The only case I can conceive of is when you don't want to commit to the function being able to compute a compile-time constant when called with known-at-compile-time arguments, e.g., if you want to preserve the flexibility to change midPoint
's implementation without changing its interface (thus potentially breaking callers). For example, you might want to preserve the flexibility to add non-constexpr
side-effects to midPoint
, e.g., IO.
推荐答案
对于变量,我没有看到任何原因不使用 constexpr
当你可以。但这并不总是可能的,例如。当变量的初始值由一个虚拟函数计算时,例如
For variables, I don't see any reason not to use constexpr
when you can. But it's not always possible to do so, e.g. when the initializer of a variable is computed by a virtual function e.g.
向函数中添加 constexpr
> interface change :表示你可以使用它来初始化 constexpr
变量的事实。这对您的函数的实现施加了约束,例如没有调用虚拟函数,没有动态内存分配和没有lambda函数作为函数对象。
Adding constexpr
to a function is an interface change: you are expressing the fact that you can use it to initialize constexpr
variables. This imposes constraints on the implementation of your function, such as no calling of virtual functions, no dynamic memory allocations and no lambda functions as function objects.
请注意, LWG问题2013 不允许标准库的实施者自由添加 constexpr
库函数。原因之一是声明一个函数 constexpr
可以禁止执行动态分配(特别是迭代器检查)的某些调试实现。这意味着 constexpr
到标准库的未来扩展需要是单独的建议。这与 noexcept
形成对比,其中图书馆作家有更多的自由。
Note that the resolution to LWG issue 2013 does not allow implementers of the Standard Library the freedom to add constexpr
to library functions. One of the reasons is that declaring a function constexpr
can inhibit certain debugging implementations that do dynamic allocations (notably iterator checking). This means that future expansions of constexpr
to the Standard Library need to be separate proposals. This is in contrast to noexcept
, where library writers have more freedom.
这篇关于有没有constexpr应该避免的情况,即使它可以使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!