代码之家  ›  专栏  ›  技术社区  ›  Vincent

在C++14中,constexpr成员可以更改数据成员吗?

  •  7
  • Vincent  · 技术社区  · 9 年前

    在C++14中,由于 constexpr 不是隐式的 const 再也不能 常量表达式 成员函数修改类的数据成员:

    struct myclass
    {
        int member;
        constexpr myclass(int input): member(input) {}
        constexpr void f() {member = 42;} // Is it allowed?
    };
    
    2 回复  |  直到 9 年前
        1
  •  3
  •   Shafik Yaghmour    9 年前

    是的,我相信这种变化是从 proposal N3598: constexpr member functions and implicit const 并最终成为 N3652: Relaxing constraints on constexpr functions 哪个更改了部分 7.1.5 段落 3 白名单中函数体允许的内容:

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

    • 空语句,
    • 静态资产声明
    • typedef声明和不定义类或枚举的别名声明,
    • 使用声明,
    • 使用指令,
    • 以及正好一个返回语句;

    至黑名单:

    其函数体应为=delete、=default或不包含

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

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

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

    理由:必须允许constexpr成员函数变异 对象

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

    struct S {
     constexpr const int &f();
     int &f();
    };
    
        2
  •  3
  •   Community CDub    4 年前

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

    a的定义 constexpr 功能应满足以下约束条件:
    它不应是虚拟的(10.3);
    其返回类型应为文本类型;
    其每个参数类型应为文字类型;
    它的 功能体 应为 = delete , = default ,或 复合语句 不包含

    • asm定义 ,
    • goto 陈述
    • 试块
    • 非文字类型、静态或线程存储持续时间或 不执行初始化。

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