【问题标题】:In C++14 can a constexpr member change a data member?在 C++14 中,constexpr 成员可以更改数据成员吗?
【发布时间】:2015-09-21 15:26:39
【问题描述】:

在 C++14 中,由于 constexpr 不再隐含 constconstexpr 成员函数可以修改类的数据成员吗:

struct myclass
{
    int member;
    constexpr myclass(int input): member(input) {}
    constexpr void f() {member = 42;} // Is it allowed?
};

【问题讨论】:

  • 你可以很容易地tried this yourself...
  • @TemplateRex 我不喜欢自己尝试 cmets,在很多情况下尝试它可能看起来有效,但程序仍然错误。对于 constexpr,我们有许多非良构 NDR 案例,例如 thisthis
  • @ShafikYaghmour 我明白你的意思,但在这种情况下,这个问题几乎没有被研究过,有几个骗子。 OP,虽然有时会问一些非常有趣的东西,但也倾向于在不做腿部工作的情况下快速提问。另请注意,您提供的 2 个问答都有可编译的代码示例...

标签: c++ constants c++14 member constexpr


【解决方案1】:

是的,我相信此更改始于 proposal N3598: constexpr member functions and implicit const 并最终成为 N3652: Relaxing constraints on constexpr functions 的一部分,该更改更改了 7.1.5 段落 3 中的白名单中允许的功能主体:

其函数体应为 = delete、= default 或 只包含复合语句

  • 空语句,
  • static_assert-declarations
  • typedef 声明和别名声明不定义类或枚举,
  • 使用声明,
  • 使用指令,
  • 只有一个返回语句;

进入黑名单:

它的函数体应该是=delete,=default,或者一个不包含的复合语句

  • asm 定义,
  • goto 语句,
  • try 块,或
  • 非文字类型或静态或线程存储持续时间的变量的定义,或 不执行初始化。

并且还在C.3.3第7条中添加了以下注释:声明:

更改:constexpr 非静态成员函数不是隐式 const 成员函数。

基本原理:必须允许 constexpr 成员函数改变 对象。

对原始功能的影响:有效的 C++ 2011 代码可能无法编译 本国际标准。例如下面的代码是有效的 在 C++ 2011 中,但在本国际标准中无效,因为它 以不同的返回类型声明相同的成员函数两次:

struct S {
 constexpr const int &f();
 int &f();
};

【讨论】:

    【解决方案2】:

    据我所知,是的。限制来自 [dcl.constexpr]:

    constexpr 函数的定义应满足以下约束:
    — 它不应是虚拟的 (10.3);
    — 它的返回类型应为文字类型;
    — 它的每个参数类型都应该是文字类型;
    — 它的function-body 应该是= delete= default,或者是一个不包含

    复合语句
    • asm 定义
    • goto 声明,
    • 一个try-block,或者
    • 非文字类型或静态或线程存储持续时间的变量的定义,或 不执行初始化。

    该功能满足所有这些要求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-05
      • 1970-01-01
      • 2015-06-03
      • 1970-01-01
      • 2020-03-10
      • 1970-01-01
      • 2022-01-03
      • 1970-01-01
      相关资源
      最近更新 更多