Could non-static member variable be modified in constexpr constructor (C++14)?

前端 未结 1 1109
清酒与你
清酒与你 2021-01-04 20:45
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;
         


        
相关标签:
1条回答
  • 2021-01-04 21:11

    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 complains:

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

    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's error message is:

    error: constexpr constructor does not have empty body

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

    Moreover, N3597 lists this example:

    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 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.

    Update (2017-10-03)

    clang fixed this, but there has been no new release yet: https://bugs.llvm.org/show_bug.cgi?id=19741 (Compiler explorer)

    0 讨论(0)
提交回复
热议问题