7

In C++14, since constexpr are not implicitly const anymore, can a constexpr member function modify a data member of a class:

struct myclass
{
    int member;
    constexpr myclass(int input): member(input) {}
    constexpr void f() {member = 42;} // Is it allowed?
};
Barry
  • 286,269
  • 29
  • 621
  • 977
Vincent
  • 57,703
  • 61
  • 205
  • 388
  • 2
    you could have easily [tried this yourself](http://coliru.stacked-crooked.com/a/d31080d797cd9dd3)... – TemplateRex Sep 21 '15 at 16:46
  • 2
    possible duplicate of [What C++14 rule prohibits constexpr functions from making assignments to data members?](http://stackoverflow.com/questions/25152301/what-c14-rule-prohibits-constexpr-functions-from-making-assignments-to-data-me) – TemplateRex Sep 21 '15 at 16:47
  • 1
    [yet another duplicate](http://stackoverflow.com/q/23647492/819272) – TemplateRex Sep 21 '15 at 16:53
  • 1
    @TemplateRex I dislike *try it for yourself* comments, there are plenty of cases where trying it out may appear to work but the program is still wrong. For constexpr we have many cases that are ill-formed NDR for example [this](http://stackoverflow.com/q/22176777/1708801) and [this](http://stackoverflow.com/q/32009602/1708801) – Shafik Yaghmour Sep 21 '15 at 16:57
  • @ShafikYaghmour I see your point, but in this case, the question was pretty much not researched at all, there are a couple of dupes. The OP, while sometimes asking really interesting stuff, also has a tendency to quick-fire questions without doing the leg work. Also note that the 2 Q&As you gave, both had compilable code examples... – TemplateRex Sep 21 '15 at 17:08

2 Answers2

3

As far as I can tell, yes. The restrictions are, from [dcl.constexpr]:

The definition of a constexpr function shall satisfy the following constraints:
— it shall not be virtual (10.3);
— its return type shall be a literal type;
— each of its parameter types shall be a literal type;
— its function-body shall be = delete, = default, or a compound-statement that does not contain

  • an asm-definition,
  • a goto statement,
  • a try-block, or
  • a definition of a variable of non-literal type or of static or thread storage duration or for which no initialization is performed.

The function meets all those requirements.

Community
  • 1
  • 1
Barry
  • 286,269
  • 29
  • 621
  • 977
3

Yes they are, I believe this change started with proposal N3598: constexpr member functions and implicit const and eventually became part of N3652: Relaxing constraints on constexpr functions which changed section 7.1.5 paragraph 3 what is allowed in the function body from a white-list:

its function-body shall be = delete, = default, or a compound-statement that contains only

  • null statements,
  • static_assert-declarations
  • typedef declarations and alias-declarations that do not define classes or enumerations,
  • using-declarations,
  • using-directives,
  • and exactly one return statement;

to a black-list:

its function-body shall be = delete, = default, or a compound-statement that does not contain

  • an asm-definition,
  • a goto statement,
  • a try-block, or
  • a definition of a variable of non-literal type or of static or thread storage duration or for which no initialization is performed.

and also added the following notes to section C.3.3 Clause 7: declarations:

Change: constexpr non-static member functions are not implicitly const member functions.

Rationale: Necessary to allow constexpr member functions to mutate the object.

Effect on original feature: Valid C++ 2011 code may fail to compile in this International Standard. For example, the following code is valid in C++ 2011 but invalid in this International Standard because it declares the same member function twice with different return types:

struct S {
 constexpr const int &f();
 int &f();
};
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740