在 C++14 中,constexpr 成员可以更改数据成员吗?
In C++14 can a constexpr member change a data member?
在 C++14 中,由于 constexpr
不再是隐含的 const
,constexpr
成员函数是否可以修改 class 的数据成员:
struct myclass
{
int member;
constexpr myclass(int input): member(input) {}
constexpr void f() {member = 42;} // Is it allowed?
};
据我所知,是的。限制来自 [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.
该功能满足所有这些要求。
是的,我相信这个变化是从 proposal N3598: constexpr member functions and implicit const and eventually became part of N3652: Relaxing constraints on constexpr functions 开始的,它改变了第 7.1.5
段 3
白名单中函数体中允许的内容:
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;
加入黑名单:
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.
并且还在第 C.3.3
节第 7 条中添加了以下注释:声明:
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();
};
在 C++14 中,由于 constexpr
不再是隐含的 const
,constexpr
成员函数是否可以修改 class 的数据成员:
struct myclass
{
int member;
constexpr myclass(int input): member(input) {}
constexpr void f() {member = 42;} // Is it allowed?
};
据我所知,是的。限制来自 [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.
该功能满足所有这些要求。
是的,我相信这个变化是从 proposal N3598: constexpr member functions and implicit const and eventually became part of N3652: Relaxing constraints on constexpr functions 开始的,它改变了第 7.1.5
段 3
白名单中函数体中允许的内容:
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;
加入黑名单:
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.
并且还在第 C.3.3
节第 7 条中添加了以下注释:声明:
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(); };