首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“按引用返回”或“按引用传递”参数何时与constexpr兼容?

“按引用返回”或“按引用传递”参数何时与constexpr兼容?
EN

Stack Overflow用户
提问于 2012-02-13 11:23:30
回答 2查看 541关注 0票数 2

标记为constexpr的函数被认为是不可变的纯函数。从"std::max() and std::min() not constexpr" post开始,您不能将常量引用输入重定向为输出,因为这将要求参数具有持久性。但是,你能通过const-reference获取一个参数吗,只要你不重新引导它?

代码语言:javascript
复制
// 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-enabled类型的子对象的常量引用?

代码语言:javascript
复制
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 ]; }
};

或者说即使是子对象返回也必须是按值返回的吗?

(很抱歉,如果这是基本的,但我找到的所有东西都绕过了这一点,实际上并不是决定性的。)

EN

回答 2

Stack Overflow用户

发布于 2012-02-13 12:28:00

该标准对constexpr函数中允许的内容非常清楚:

§7.1.5 [dcl.constexpr] p3

constexpr函数的定义应满足以下约束:

  • ...
  • 其返回类型应为文字类型;
  • 其每个参数类型均应为文字类型

§3.9 [basic.types] p10

符合以下条件的类型是文字类型:

引用标量类型;or

  • a
  • 类型;copy或
  • 具有以下所有条件的类类型(第9条)具有简单的析构函数,
    • 非静态数据成员(如果有的话)的括号或相等初始化器中的每个构造函数调用和完整表达式都是常量表达式(5.19),
    • 它是聚合类型(8.5.1)或至少有一个常量copy构造函数或不是复制或移动构造函数的构造函数模板,
    • 它具有所有非静态数据成员和文字类型的基类;or

  • 文字类型的数组。

因此,是的,你可以有引用参数,甚至是引用到非常数的参数。constexpr函数的参数受到另一种方式的限制。完整、详尽的列表可以在§5.19 [expr.const] p2下找到。下面摘录一下是什么让constexpr声明的函数不再那么constexpr了:

条件表达式是核心常量表达式,除非它包含以下内容之一作为可能求值的子表达式(3.2),但不考虑未求值的逻辑AND (5.14)、逻辑OR (5.15)和条件(5.16)运算的子表达式注意:重载运算符会调用函数。-end备注:

(关于逻辑运算符的最后一点只是意味着它的未计算部分(由于短路计算)不是确定函数是否真正为constexpr的操作的一部分。)

  • ...
  • a dynamic cast (5.2.7);
  • a reinterpret_cast (5.2.10);
  • a伪析构函数调用(5.2.4);
  • increment或减量操作(5.2.6,5.3.2);
  • a typeid expression (5.2.8),其操作数属于多态类类型;
  • a new-expression (5.3.4);删除表达式(5.3.5);删除表达式(5.3.5);两个操作数都是指针的减法(5.7);unspecified;
  • an赋值或复合赋值(5.17)的关系运算符(5.9)或相等运算符(5.10);or
  • ...

(

  • a

  • )
票数 4
EN

Stack Overflow用户

发布于 2012-03-02 14:18:36

Core issue 1454的解决方案改变了约翰尼斯在回答the std::max question时所引用的规则。随着该问题的当前解决方案(由g++和clang实现),constexpr函数被允许通过引用返回它们可以计算的任何左值。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9255185

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档