Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[C++14][言語機能] constexpr緩和の記事に数点追記 #1016

Merged
merged 2 commits into from
Jan 5, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions lang/cpp14/relaxing_constraints_on_constexpr.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,9 @@ C++11で、汎用定数式の機能である[`constexpr`](/lang/cpp11/constexpr.
- `if`文と`switch`文を許可
- 全てのループ文を許可(`for`文、範囲`for`文、`while`文、`do-while`文)
- 変数の書き換えを許可
- 戻り値型(リテラル型)として、`void`を許可
- 戻り値型(リテラル型)として、`void`を許可 / 戻り値型や関数引数で非`const`参照を許可
- `constexpr`非静的メンバ関数の、暗黙の`const`修飾を削除
- `constexpr`コンストラクタがbodyを持てるようになった


## 仕様
Expand Down Expand Up @@ -137,11 +138,13 @@ constexpr int square(int n)
```


### `constexpr`関数の戻り値型として、`void`を許可
### `constexpr`関数の戻り値型として、`void`を許可 / 戻り値型や関数引数で非`const`参照を許可
`constexpr`関数での、パラメータの型、および戻り値の型は、[リテラル型](/reference/type_traits/is_literal_type.md)に分類される型に限定される。

C++14では、[リテラル型](/reference/type_traits/is_literal_type.md)に分類される型に、`void`が追加された。

また、戻り値型や関数引数で非`const`参照を使うことが許可された。

これにより、`constexpr`関数の戻り値型を`void`とし、非`const`参照のパラメータを書き換えて結果を返す、という操作が許可された。

```cpp
Expand Down Expand Up @@ -173,6 +176,19 @@ C++14ではこの仕様が削除され、`const`か非`const`かを、明示的
※この変更によって、既存コードの互換性は壊れない。


### `constexpr`コンストラクタがbodyを持てるようになった
C++11では、`constexpr`コンストラクタのbodyには以下の要素しか持たせることを許されていなかった:

- ヌル文
- `static_assert`
- クラスや列挙型を定義しない、別の型名定義
- `using`宣言と、`using`ディレクティブ

これは事実上`constexpr`コンストラクタのbodyが空でなければいけないことを意味している。

C++14では`constexpr`コンストラクタのbodyに関する制約は一般の`constexpr`関数に従うようになったため、body内でローカル変数を定義したり引数に応じたメンバ変数の書き換えを行ったりすることが許可された。


## この機能が必要になった背景・経緯
C++は直交性を重視して設計されており、直接関係ない機能同士を組み合わせて使用できる。しかし、C++11での`constexpr`は、その制限によって、ほかの機能(インスタンス、`for`ループ、変数書き換え、例外等)とうまく組み合わせられなかった。

Expand Down