何时“按引用返回”?或“按引用传递”参数与 constexpr 兼容吗?
标记为 constexpr 的函数应该是不可变的纯函数。来自 “std::max() 和 std::min() 不是 constexpr” post,您不能将常量引用输入重新引导为输出,因为这需要参数具有永久性。但是,只要不重新引导它,您可以通过 const 引用获取参数吗?
// Is this still constexpr?
// (Assuming that std::complex is constexpr-safe, as it's supposed to be.)
constexpr
int MySum( std::complex<double> const &a, std::complex<double> const &b )
{ return static_cast<int>( a.real() + b.real() ); }
相反,您可以返回对启用 constexpr 的类型的子对象的 const 引用吗?
template <typename T>
class MyComplex
{
T c_[ 2 ];
public:
constexpr MyComplex( T r = T(), T i = T() )
: c_{ r, i }
{}
// Is this actually constexpr?
constexpr T const & operator[]( unsigned l ) //const
{ return c_[ l ]; }
// Can't be constexpr
T & operator[]( unsigned l ) { return c_[ l ]; }
};
或者甚至子对象返回也必须按值返回?
(抱歉,如果这是基本的,但我发现的所有内容都围绕这一点跳舞,但实际上并没有确定。)
Functions marked constexpr are supposed to be immutable pure functions. From the "std::max() and std::min() not constexpr" post, you can't re-channel a const-reference input as an output, since that would require the parameter to have permanence. But can you take a parameter by const
-reference, as long as you don't re-channel it?
// Is this still constexpr?
// (Assuming that std::complex is constexpr-safe, as it's supposed to be.)
constexpr
int MySum( std::complex<double> const &a, std::complex<double> const &b )
{ return static_cast<int>( a.real() + b.real() ); }
Conversely, can you return a const-reference to a sub-object of a constexpr
-enabled type?
template <typename T>
class MyComplex
{
T c_[ 2 ];
public:
constexpr MyComplex( T r = T(), T i = T() )
: c_{ r, i }
{}
// Is this actually constexpr?
constexpr T const & operator[]( unsigned l ) //const
{ return c_[ l ]; }
// Can't be constexpr
T & operator[]( unsigned l ) { return c_[ l ]; }
};
Or do even sub-object returns have to be by value?
(Sorry if this is basic, but everything I've found dances around this point without actually being definitive.)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
该标准对于
constexpr
函数中允许的内容非常清楚:§7.1.5 [dcl.constexpr] p3
§3.9 [基本类型] p10
因此,是的,您可以拥有引用参数,甚至是对非常量参数的引用。 constexpr 函数的参数以另一种方式受到限制。完整、详尽的列表可以在
§5.19 [expr.const] p2
下找到。下面摘录了constexpr
声明的函数不再那么constexpr
的原因:关于逻辑运算符的最后一点只是意味着它的未计算部分(由于短路计算)不是确定该函数是否真正<代码> constexpr 。)
The standard is pretty clear on what is allowed in a
constexpr
function:§7.1.5 [dcl.constexpr] p3
§3.9 [basic.types] p10
As such, yes, you can have reference parameters, even reference-to-non-const ones. The parameters of a
constexpr
function are restricted in another way. The complete, exhaustive list can be found under§5.19 [expr.const] p2
. Here's an excerpt of what makes aconstexpr
declared function not-so-constexpr
anymore:(The last bit about the logical operators just means that the unevaluated part of it (due to short-circuit evaluation) is not part of the operations that determine whether the function is truly
constexpr
.)核心问题 1454 的解决方案更改了约翰内斯在他对 std::max 问题。通过该问题的当前解决方案(由 g++ 和 clang 实现),constexpr 函数可以通过引用返回它们可以计算的任何左值。
Core issue 1454's resolution changes the rule which Johannes is referencing in his answer to the std::max question. With the current resolution of that issue (which is implemented by both g++ and clang),
constexpr
functions are allowed to return, by reference, any lvalue which they can compute.