是否可以在constexpr构造函数(C ++ 14)中修改非静态成员变量? [英] Could non-static member variable be modified in constexpr constructor (C++14)?

查看:1138
本文介绍了是否可以在constexpr构造函数(C ++ 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(with -std = c ++ 1y)

  • 系统:Linux 3.2

  • 如果我删除L2,这段代码编译。如果我添加L2,编译器抱怨修改const限定类型的对象const int不允许在常量表达式。我不是一个语言律师,所以我不知道这是否是真的。但是,如果是,为什么编译器没有抱怨L1,因为它也称为A()作为constexpr?这是a的bug吗?

    If I delete L2, this code compiles. If I add L2, the compiler complained "modification of object of const-qualified type 'const int' is not allowed in a constant expression". I am not a language lawyer, so I am not sure whether this is true. However, if it is, why compiler didn't complain anything about L1, since it also called A() as constexpr? Is this a bug of clang? Or did I miss anything?

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

    BTW,如果我更改constexpr A a到A a (删除constexpr关键字),L1编译失败,期望。

    BTW, if I change "constexpr A a;" to "A a;" (remove constexpr keyword), L1 failed to compile which is expect. However, the compiler didn't complain about L2 anymore.

    在线编译器URL: http://goo.gl/AoTzYx

    推荐答案

    我相信这只是一个编译器没有赶上C ++ 14提出的更改。您的 constexpr 构造函数满足 N3936 gcc和clang无法编译您的代码,但出于不同的原因。

    I believe this is just a case of compilers not having caught up to the changes proposed for C++14. Your constexpr constructor satisfies all the conditions listed in §7.1.5/4 of N3936. Both gcc and clang fail to compile your code, but for different reasons.

    clang抱怨:


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

    note: modification of object of const-qualified type 'const int' is not allowed in a constant expression

    这是没有意义的,但让我想起C ++ 11的限制, code> constexpr 成员函数是隐式的 const (这是一个构造函数,并不适用,但错误消息是reminiscent的)。此限制对于C ++ 14也已取消。

    which doesn't make much sense, but reminds me of the C++11 restriction that constexpr member functions are implicitly const (this is a constructor, and that doesn't apply, but the error message is reminiscent of that). This restriction was also lifted for C++14.

    gcc的错误消息是:

    gcc's error message is:


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

    error: constexpr constructor does not have empty body

    看起来很清楚gcc仍然实现C ++ 11规则 constexpr 构造函数。

    Seems pretty clear that gcc still implements the C++11 rules for constexpr constructors.

    此外, 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 ,其中包含当前草稿中的字词。不幸的是,前面的例子消失了,但是,现在的语句中没有什么能说明你不能在 constexpr 构造函数体中为数据成员赋值。

    N3597 was superseded by N3652, which contains the wording found in the current draft. Unfortunately, the earlier example disappears, but, again, nothing in the current wording says you cannot assign values to data members within the body of a constexpr constructor.

    这篇关于是否可以在constexpr构造函数(C ++ 14)中修改非静态成员变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆