diff --git a/implementation-status.md b/implementation-status.md index 1f84eb4d98..e64ce6a56f 100644 --- a/implementation-status.md +++ b/implementation-status.md @@ -181,7 +181,7 @@ | P0614R1: [初期化式をともなう範囲for文](/lang/cpp20/range-based_for_statements_with_initializer.md) | 範囲for文スコープで使用する変数の初期化のための構文を追加 | 9 | 8.0 | | 2019 Update 5 | | P0588R1: [暗黙のラムダキャプチャを簡略化](/lang/cpp20/simplifying_implicit_lambda_capture.md) | ラムダ式のキャプチャに関する仕様整理 | 8 | No | 2021.4 | 2019 Update 4 | | P0846R0: [関数テンプレートに明示的に型指定した場合にADLで見つからない問題を修正](/lang/cpp20/adl_and_function_templates_that_are_not_visible.md) | 名前空間内の関数テンプレートをテンプレート引数指定かつ非修飾・ADLで正しく呼び出せるよう修正 | 9 | 9.0 | 2021.4 | 2019 Update 1 | -| P0641R2: [デフォルトのコピーコンストラクタと非`const`なコンストラクタが衝突する問題を修正](/lang/cpp20/resolving_const_mismatch_with_defaulted_copy_constructor.md.nolink) | | 9 | 8.0 | 2021.4 | 2015 | +| P0641R2: [デフォルトのコピーコンストラクタと非`const`なコンストラクタが衝突する問題を修正](/lang/cpp20/resolving_const_mismatch_with_defaulted_copy_constructor.md) | 非`const`なオブジェクトをとるコンストラクタを定義すると、そのクラスをラップしたクラスのコピーコンストラクタが不適格になってしまう問題を修正 | 9 | 8.0 | 2021.4 | 2015 | | P0859R0: [評価されない文脈での定数式評価によって特殊メンバ関数がインスタンス化されることを規定](/lang/cpp20/less_eager_instantiation_of_constexpr_functions.md) | `sizeof`や`decltype`などの評価されない文脈において定数式評価を行った場合に、ムーブコンストラクタのような特殊メンバ関数が定義されることを規定 | 9 | 8 | | Partial in 2019 Update 7 | | P0515R3: [一貫比較](/lang/cpp20/consistent_comparison.md) | 三方比較演算子によって比較演算子の自動生成を行うようにする | 10 | 8.0 (partial) | 2021.4 | 2019 | | P0692R1: [特殊化のアクセスチェック](/lang/cpp20/access_checking_on_specializations.md) | | Yes | partial | 2021.4 | 2019 Update 6 | diff --git a/lang/cpp20.md b/lang/cpp20.md index cd33ace93f..03107560fe 100644 --- a/lang/cpp20.md +++ b/lang/cpp20.md @@ -15,7 +15,7 @@ C++20とは、2020年中に改訂され、ISO/IEC 14882:2020で標準規格化 | [ビットフィールドのメンバ変数初期化](cpp20/default_member_initializers_for_bit_fields.md) | ビットフィールドメンバ変数のデフォルト値を設定する構文を追加する | | [関数を条件付きで`explicit`にする構文を追加](cpp20/explicit_bool.md) | `explicit(true)`のように`explicit`に真理値パラメータを指定できるようにする | | [`const`修飾されたメンバポインタの制限を修正](cpp20/fixing_const_qualified_pointers_to_members.md) | `.*`演算子での左辺値の`const`メンバ関数呼び出しを許可する | -| [デフォルトのコピーコンストラクタと非`const`なコンストラクタが衝突する問題を修正](cpp20/resolving_const_mismatch_with_defaulted_copy_constructor.md.nolink) | | +| [デフォルトのコピーコンストラクタと非`const`なコンストラクタが衝突する問題を修正](cpp20/resolving_const_mismatch_with_defaulted_copy_constructor.md) | 非`const`なオブジェクトをとるコンストラクタを定義すると、そのクラスをラップしたクラスのコピーコンストラクタが不適格になってしまう問題を修正 | | [特殊化のアクセスチェック](cpp20/access_checking_on_specializations.md) | | | [空オブジェクトに対する最適化を支援する属性`[[no_unique_address]]`](cpp20/language_support_for_empty_objects.md) | `[[no_unique_address]]`属性を導入し、空の型のオブジェクトをほかのオブジェクトと共有する最適化を許可する | | [friend指定された関数内から構造化束縛を使用して非公開メンバ変数にアクセスすることを許可](cpp20/allow_structured_bindings_to_accessible_members.md) | 構造化束縛の仕様として公開メンバ変数のみを取り出せるようになっていたが、friend指定された関数からは非公開メンバ変数にもアクセスできるようにする | diff --git a/lang/cpp20/resolving_const_mismatch_with_defaulted_copy_constructor.md b/lang/cpp20/resolving_const_mismatch_with_defaulted_copy_constructor.md new file mode 100644 index 0000000000..3e7fc3e37e --- /dev/null +++ b/lang/cpp20/resolving_const_mismatch_with_defaulted_copy_constructor.md @@ -0,0 +1,41 @@ +# デフォルトのコピーコンストラクタと非constなコンストラクタが衝突する問題を修正 +* cpp20[meta cpp] + +## 概要 +C++17までは以下のように、自身の型の非`const`なオブジェクトをとるコンストラクタをもつクラスを定義し、 + +```cpp +struct MyType { + MyType(MyType&); // パラメータがconstではない +}; +``` + +そのクラスオブジェクトをメンバ変数としてもつクラスを定義し、コピーコンストラクタをデフォルト定義すると、プログラムは不適格となってしまう。 + +```cpp +template +struct Wrapper { + Wrapper(const Wrapper&) = default; + T t; +}; + +Wrapper var; // インスタンス化に失敗する +``` + +しかし、`Wrapper`をコピーしない限り、そのオブジェクトは使えるはずである。これはとくに[`std::tuple`](/reference/tuple/tuple.md)の実装で問題となる。 + +C++20では、このコードを適格とする。 + + +## 仕様 +- 明示的にデフォルト化された特殊メンバ関数のパラメータ型は、暗黙宣言された場合のパラメータ型と以下のように異なることを許可する: + - 参照修飾が異なる + - コピーコンストラクタとコピー代入演算子の場合、パラメータの型は「非`const`な`T`への参照」であってもかまわない +- それ以外の方法で型が異なる場合、以下のようになる: + - 特殊メンバ関数が代入演算子であり、戻り値の型が異なるか、パラメータの型が参照でない場合、 プログラムは不適格となる + - そうでない場合、その特殊メンバ関数が最初の宣言で明示的にデフォルト化されていれば、その関数は削除されたものとして定義される + - そうでない場合、プログラムは不適格となる + + +## 参照 +- [P0641R2 Resolving Core Issue #1331 (`const` mismatch with defaulted copy constructor)](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0641r2.html)