当前位置: 首页 > 知识库问答 >
问题:

可以在constexpr构造函数(C 14)中修改非静态成员变量吗?

微生烨然
2023-03-14
struct A {
    int a = 0;
    constexpr A() { a = 1; }
};

constexpr bool f() {
    constexpr A a;
    static_assert(a.a == 1, ""); // L1: OK
    return a.a == 1;
}
static_assert(f(), ""); // L2: Error, can not modify A::a in constexpr
  • 联机编译器URL:http://goo.gl/jni6Em
  • 编译器:clang 3.4(带有-std=c 1y)
  • 系统:Linux 3.2

如果删除L2,则编译此代码。如果我添加L2,编译器会抱怨“常量表达式中不允许修改常量限定类型‘const int‘的对象”。我不是语言律师,所以我不确定这是否属实。然而,若确实如此,为什么编译器并没有抱怨L1,因为它也将A()作为constexpr调用?这是叮当声吗?还是我错过了什么?

参考:http://en.cppreference.com/w/cpp/language/constexpr

顺便说一句,如果我将“配置文件A a;”更改为“配置文件A;”(删除配置文件关键字),L1编译失败,这是意料之中的。然而,编译器不再抱怨L2了。

关于此的在线编译器URL:http://goo.gl/AoTzYx

共有1个答案

束建章
2023-03-14

我认为这只是编译器没有赶上针对C 14提出的更改的情况。您的constexpr构造函数满足N3936的§7.1.5/4中列出的所有条件。gcc和clang都无法编译您的代码,但原因不同。

铿锵抱怨:

注意:常量表达式中不允许修改常量限定类型“const int”的对象

这没有多大意义,但让我想起了C 11的限制,即< code>constexpr成员函数是隐式< code>const(这是一个构造函数,这并不适用,但错误消息会让人想起这一点)。这一限制对C 14也取消了。

gcc的错误信息是:

错误:constexpr 构造函数没有空体

似乎很清楚,gcc 仍然为 constexpr 构造函数实现 C 11 规则。

此外,N3597 列出了此示例:

struct override_raii {
  constexpr override_raii(int &a, int v) : a(a), old(a) {
    a = v;
  }
  constexpr ~override_raii() {
    a = old;
  }
  int &a, old;
};

N3597被N3652取代,n 3652包含了当前草案中的措辞。不幸的是,前面的例子消失了,但是,再一次,在当前的措辞中,没有任何内容说您不能在< code>constexpr构造函数体中为数据成员赋值。

clang修复了这个问题,但是还没有新的版本:https://bugs.llvm.org/show_bug.cgi?id=19741(编译器资源管理器)

 类似资料:
  • 问题内容: 我想知道非静态方法如何修改静态变量。我知道静态方法只能访问其他静态方法和静态变量。但是,另一面是真的吗?非静态方法只能访问非静态变量吗?例如: 这段代码可以编译,我想知道为什么要使用静态访问特权。 问题答案: 我已经从The Java Tutorials找到了 实例方法可以直接访问实例变量和实例方法。 实例方法可以直接访问类变量和类方法。 类方法可以直接访问类变量和类方法。 类方法不能

  • 本文向大家介绍C++中静态成员函数与静态成员变量(static ),包括了C++中静态成员函数与静态成员变量(static )的使用技巧和注意事项,需要的朋友参考一下 C++中静态成员函数与静态成员变量(static ) 这篇介绍了静态成员函数与静态成员变量,是我的读书笔记,我希望它够简短但又比较全面,起到复习的作用。如果有一些C++知识记不清楚了,它可以帮你很快回忆起来。 复习C语言的stati

  • 本文向大家介绍PHP静态成员变量和非静态成员变量详解,包括了PHP静态成员变量和非静态成员变量详解的使用技巧和注意事项,需要的朋友参考一下 数据成员可以分静态变量、非静态变量两种. 静态成员:静态类中的成员加入static修饰符,即是静态成员.可以直接使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员不能访问非静态的成员..因为静态成员存在于

  • 我遇到了我不明白的情况。有人能很好地解释为什么第一个代码编译正确,而第二个代码出错: 错误:“TestClass::z”的值在常量表达式中不可用。} - ^ 注意:“int TestClass::z”不是const static int z;" 工作代码: 但是当我尝试使 静态时,我得到上述错误: 附言:我正在使用mingw32-g 4.8.1

  • 看看这段代码: < code>Foo有一个成员< code > Foo::bar::nonConstexpr ,它有一个非Constexpr构造函数。所以,我的期望是,这不应该编译。但是它用gcc,clang和msvc编译。这是编译器的bug,还是某个规则允许这段代码编译? 如果我直接将 成员添加到 中,代码将不再编译。 (我遇到了这个问题,因为我期望对全局对象进行静态初始化,但它得到了动态初始化

  • 在C 14中,由于<code>constexpr</code>不再是隐式<code>常量</code<,所以<code>constexpr<-code>成员函数是否可以修改类的数据成员: