強そうな人からC++のclassに関連する謎な用語を使われたときにみるもの
C++を使うにあたって規格書を読まないということはありえないので、どうしても専門用語が多くなっしまいます。
誰かに質問したときに謎な専門用語が混じっていることもあるかと思います。そんな時のためにかるく解説をします。
ただし、
C++入門者に贈るclass入門とclass/structキーワードの使い分け
の内容を理解していることを前提とします。
以下、規格書の引用部分でバージョン間で差異のある部分、及びそれに該当する解説箇所は赤字で示します。
追記
お知らせするのを完全に忘れていたのですが、
にC++20に対応させた内容を記載したのでそちらを参照してください。
user-declared
残念ながら規格書を読んでも判然としません。ただ、ユーザーが関数を宣言したらuser-declared
になるようです。= default
/= delete
指定も含むと解するべきかと思われます。
言い換えると、= delete
指定しても宣言は残っている、と。
宣言が残っていればいいんですね。
user-provided
N3337(C++11)
§ 8.4.2.5 dcl.fct.def.default
A special member function isuser-provided
if it is user-declared and not explicitly defaulted or deleted on its first declaration.
N4140(C++14)
§ 8.4.2.5 dcl.fct.def.default
A function isuser-provided
if it is user-declared and not explicitly defaulted or deleted on its first declaration.
N4659(C++17)
§ 11.4.2.5 dcl.fct.def.default
A function isuser-provided
if it is user-declared and not explicitly defaulted or deleted on its first declaration.
not A or Bは、(!A && !B) <=> !(A || B)
という意味なので、not explicitlyはdefaultedとdeletedにかかっています。
cf.) https://oshiete.goo.ne.jp/qa/2089050.html
andまで含めて解釈すると、A && (!(B || C))
と解釈するべきです。
つまり、先のuser-declared
から= default
/= delete
指定されたものを除くもの、となっています。C++11だと特殊メンバ関数に対してのみの定義になっていますが、言っていることとしては同じですね。
大事なことだからもう一度、= default
/= delete
指定されたものはuser-providedではありません。
class Hoge {
public:
Hoge() {}//user-provided
Hoge(const Hoge&) = default;//not user-provided, but user-declared
Hoge(Hoge&&) = delete;//not user-provided, but user-declared
};
int f(Hoge&&);//user-provided
int f(const Hoge&) = delete;//not user-provided, but user-declared
int main(){
Hoge h;
//f(h);
f(Hoge());
}
こういうことか?宣言の形態についてであって、定義についてはみていなさそう。
trivial
それ単体は規格では定義されていません。英単語的には、自明な、というような意味らしいです。
"trivial"というのは"コンパイラがシンボルを作成する必要がない"ということのような気がするな。もちろん規格には実装がどう振る舞うかは書いてないわけだけど
— 白山風露 (@kazatsuyu) 2017年6月9日
まあtrivialだからってシンボルを作成しないとも限りませんしねhttps://t.co/h6XFHBdTsh
— 白山風露 (@kazatsuyu) 2017年6月10日
ただこのあと見ていくようにuser-provided
ではないことが最低要件になっていて、そうするとこの推測は正しい気がします。ゆるふわ定義。
trivialなデストラクタを持つ(has a trivial destructor)
N3337(C++11)
§ 12.4.5 class.dtor
A destructor is trivial if it is not user-provided and if:
— the destructor is not virtual,
— all of the direct base classes of its class have trivial destructors, and
— for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor.
Otherwise, the destructor is non-trivial.
N4140(C++14)
§ 12.4.5 class.dtor
5 A destructor is trivial if it is not user-provided and if:
(5.4) — the destructor is not virtual,
(5.5) — all of the direct base classes of its class have trivial destructors, and
(5.6) — for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor.
Otherwise, the destructor is non-trivial.
N4659(C++17)
§ 15.4.6 class.dtor
6 A destructor is trivial if it is not user-provided and if:
(6.1) — the destructor is not virtual,
(6.2) — all of the direct base classes of its class have trivial destructors, and
(6.3) — for all of the non-static data members of its class that are of class type (or array thereof), each such class has a trivial destructor.
Otherwise, the destructor is non-trivial.
C++17で定義している節が移動しましたが、内容は変わっていません。
対象となるクラスがtrivialなデストラクタを持つためには
- デストラクタは
user-provided
ではない - デストラクターはvirtualではない
ことが大前提になります。
user-provided
ではない、とは**= default
/= delete
指定していてもいい**、ということです。
デストラクタをdeleteってどういうこと?という人は
C++ - C++11で、デストラクタ = deleteとする意味について(35601)|teratail
を見に行きましょう。
さらに
- 非staticデータメンバーのデストラクターは、すべてtrivialである
非staticメンバ変数にも上記の2条件が適応されます。
もし対象となるクラスが基底クラスを保つ場合は(なんか継承している場合)
- 直接の基底クラスのデストラクターは、すべてtrivialである
このように追加条件があります。これは言い換えると、継承関係にあるクラスのうち基底クラス方向すべてのクラスが上記3条件を満たす必要があるということです。
なぜならvirtual指定された関数と同名の関数を派生クラスで定義するとそれもvirtualになるからです。もちろんデストラクタも例外ではありません。
cf.) そのoverride指定は合法ですか?違法ですか?
C++で継承関係を作るとき、多くの場合安全性を考えて基底クラスのデストラクタをvirtual指定します。
C++では基底クラスにvirtualデストラクタを書こう - *「ふっかつのじゅもんがちがいます。」withぬこ
しかし、その時点でtrivialなデストラクタを持っていないんですね。
デストラクターはvirtualではない、とは
class HasNotUserProvidedVitrualDtorClass {
public:
virtual ~HasNotUserProvidedVitrualDtorClass() = default;
};
= default
指定されたvirtualデストラクタを除外するための条件です。
trivialに破棄可能(trivially destructible)
trivialに破棄可能とは、
- trivialなデストラクタを持つ(has a trivial destructor)
- デストラクタが削除されていない(is destructible)
の2条件を満たすものを言います。trivialなデストラクタを持つ、とtrivialに破棄可能、は同義ではありません
デストラクタが削除されていない、とは=delete
指定されている場合(explicitly deleted)や、暗黙に削除されている場合などを含みます。
これはstd::is_destructible
で調査可能です。
条件をみたすかどうかは、std::is_trivially_destructible
で調べることができます。
#include <type_traits>
struct C1 {
// トリビアルなデストラクタを持っている
// 特殊関数ではないメンバ関数は持っている
int f(int x) const { return x; }
};
struct C2 {
// 非トリビアルなデストラクタを持っている
~C2() {}
};
// 組み込み型は全てトリビアルに破棄可能
static_assert(std::is_trivially_destructible<int>::value == true, "int is trivially destructible");
static_assert(std::is_trivially_destructible<int*>::value == true, "int* is trivially destructible");
// ユーザー定義型は、ユーザー定義のデストラクタを持っていなければトリビアルに破棄可能
static_assert(std::is_trivially_destructible<C1>::value == true, "C1 is trivially destructible");
static_assert(std::is_trivially_destructible<C2>::value == false, "C2 isn't trivially destructible");
int main() {}
trivialなコピー/ムーブコンストラクタを持つ(has a trivial copy/move constructor)
N3337(C++11)
§ 12.8 class.copy
12 A copy/move constructor for class X is trivial if it is not user-provided and if
— class X has no virtual functions (10.3) and no virtual base classes (10.1), and
— the constructor selected to copy/move each direct base class subobject is trivial, and
— for each non-static data member of X that is of class type (or array thereof), the constructor selected to copy/move that member is trivial;
otherwise the copy/move constructor is non-trivial.
N4140(C++14)
§ 12.8 class.copy
12 A copy/move constructor for class X is trivial if it is not user-provided, its parameter-type-list is equivalent to the parameter-type-list of an implicit declaration, and if
(12.1) — class X has no virtual functions (10.3) and no virtual base classes (10.1), and
(12.2) — class X has no non-static data members of volatile-qualified type, and
(12.3) — the constructor selected to copy/move each direct base class subobject is trivial, and
(12.4) — for each non-static data member of X that is of class type (or array thereof), the constructor selected to copy/move that member is trivial;
otherwise the copy/move constructor is non-trivial.
N4569(C++17)
§ 15.8.1 class.copy.ctor
11 A copy/move constructor for class X is trivial if it is not user-provided and if:
(11.1) — class X has no virtual functions (13.3) and no virtual base classes (13.1), and
(11.2) — the constructor selected to copy/move each direct base class subobject is trivial, and
(11.3) — for each non-static data member of X that is of class type (or array thereof), the constructor selected to copy/move that member is trivial;
otherwise the copy/move constructor is non-trivial.
ただし、CWG issue 2171により、以下の文面は削除されます。
, its parameter-type-list is equivalent to the parameter-type-list of an implicit declaration,
また、CWG issue 2094により、以下の文面は削除されます。
class X has no non-static data members of volatile-qualified type, and
C++17から定義している節が移動しました。
対象となるクラスがtrivialなコピー/ムーブコンストラクタを持つためには
- コピー/ムーブコンストラクタは
user-provided
ではない - virtual関数を持たず、virtual基本クラスも持たない
- (C++14のみ、CWG issue 2171適用前のみ)コンストラクタ/代入演算子の仮引数リストが暗黙に宣言された場合の仮引数リストと同じ
- (C++14のみ、CWG issue 2094適用前のみ)volatile修飾された型の非staticデータメンバーを持たない
が前提条件です。また、
- クラス型か、クラスの配列型の非staticデータメンバーをコピー/ムーブするのに使われるコンストラクターがトリビアルであること
非staticメンバ変数についても先の4条件が適応されます。
もし対象となるクラスが基底クラスを保つ場合は(なんか継承している場合)
- 直接の基底クラスのサブオブジェクトをコピー/ムーブするのに使われるコンストラクターがトリビアルであること
このように追加条件があります。これは言い換えると、継承関係にあるクラスのうち基底クラス方向すべてのクラスが上記5条件を満たす必要があるということです。
trivialなデストラクタの要件と大きく違うのは、virtual関数を持っていはいけないことでしょうか。
仮引数リストが暗黙に宣言された場合の仮引数リストと同じ、というのは正直何言っているのかわからないです。ユーザー定義してはいけないんだから嫌でも暗黙に宣言された場合の仮引数リストと同じになると思うんですが・・・。CWG issue 2171により削除されました
これはあれか?コピー/ムーブコンストラクタを= delete
する場合はX(const X&)
/X(X&&)
に対してのみ= delete
しろってことか?しかもこの文言、C++14のみあるんだよな・・・、何なんだ一体・・・。
volatileの話もなぜかC++14だけあってよくわからないです。
tirivalにコピー/ムーブ構築可能(trivially copy/move constructible)
tirivalにコピー/ムーブ構築可能、であるためには
- trivialなコピー/ムーブコンストラクタを持つ(has copy/move constructor)
- コピー/ムーブ構築可能(is copy/move constructible)
の2条件を満たす必要があります。
コピー/ムーブ構築可能とは、特定の引数のときに構築可能(is constructible)、に定義がたらい回されており、これは
N3337(C++11)
§ 20.10.4.3 meta.unary.prop
6 Given the following function prototype:
template <class T>
typename add_rvalue_reference<T>::type create();
the predicate condition for a template specialization
is_constructible<T, Args...>
shall be satisfied if and only if the following variable definition would be well-formed for some invented variable t:
T t(create<Args>()...);
[ Note: These tokens are never interpreted as a function declaration. —end note ] Access checking is
performed as if in a context unrelated toT
and any of theArgs
. Only the validity of the immediate context of the variable initialization is considered. [ Note: The evaluation of the initialization can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on. Such side effects are not in the “immediate context” and can result in the program being ill-formed. —end note ]
N4140(C++14)
§ 20.10.4.3 meta.unary.prop
7 Given the following function prototype:
template <class T>
add_rvalue_reference_t<T> create() noexcept;
the predicate condition for a template specialization
is_constructible<T, Args...>
shall be satisfied if and only if the following variable definition would be well-formed for some invented variable t:
T t(create<Args>()...);
[ Note: These tokens are never interpreted as a function declaration. —end note ] Access checking is performed as if in a context unrelated to
T
and any of theArgs
. Only the validity of the immediate context of the variable initialization is considered. [ Note: The evaluation of the initialization can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on. Such side effects are not in the “immediate context” and can result in the program being ill-formed. —end note ]
N4569
§ 23.15.4.3 meta.unary.prop
8 The predicate condition for a template specializationis_constructible<T, Args...>
shall be satisfied if and only if the following variable definition would be well-formed for some invented variable t:
T t(declval<Args>()...);
[ Note: These tokens are never interpreted as a function declaration. —end note ] Access checking is performed as if in a context unrelated to
T
and any of theArgs
. Only the validity of the immediate context of the variable initialization is considered. [ Note: The evaluation of the initialization can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on. Such side effects are not in the “immediate context” and can result in the program being ill-formed. —end note ]
まあなんかごちゃごちゃ書いている上にC++17からstd::declval
を使う定義に書き換わっていますが、ようはpublicに宣言されているコンストラクタに指定の引数を渡して見たときにエラーが起きない、つまり呼び出せれば特定の引数のときに構築可能(is constructible)だ、という極めてありきたりな定義になっています。これはstd::is_constrictible
で調べられます。
で、話を戻してtirivalにコピー/ムーブ構築可能かどうかはstd::is_trivially_copy_constructible
/std::is_trivially_move_constructible
で調べられます。
trivialなコピー/ムーブ代入演算子を持つ(trivially copy/move assignable)
N3337(C++11)
§ 12.8 class.copy
25 A copy/move assignment operator for class X is trivial if it is not user-provided and if
— class X has no virtual functions (10.3) and no virtual base classes (10.1), and
— the assignment operator selected to copy/move each direct base class subobject is trivial, and
— for each non-static data member of X that is of class type (or array thereof), the assignment operator selected to copy/move that member is trivial;
otherwise the copy/move assignment operator is non-trivial.N4140(C++14)
§ 12.8 class.copy
25 A copy/move assignment operator for class X is trivial if it is not user-provided, its parameter-type-list is equivalent to the parameter-type-list of an implicit declaration, and if
(25.1) — class X has no virtual functions (10.3) and no virtual base classes (10.1), and
(25.2) — class X has no non-static data members of volatile-qualified type, and
(25.3) — the assignment operator selected to copy/move each direct base class subobject is trivial, and
(25.4) — for each non-static data member of X that is of class type (or array thereof), the assignment operator selected to copy/move that member is trivial;
otherwise the copy/move assignment operator is non-trivial.N4659(C++17)
§ 15.8.2 class.copy.assign
9 A copy/move assignment operator for class X is trivial if it is not user-provided and if:
(9.1) — class X has no virtual functions (13.3) and no virtual base classes (13.1), and
(9.2) — the assignment operator selected to copy/move each direct base class subobject is trivial, and
(9.3) — for each non-static data member of X that is of class type (or array thereof), the assignment operator selected to copy/move that member is trivial;
otherwise the copy/move assignment operator is non-trivial.
ただし、CWG issue 2171により、以下の文面は削除されます。
, its parameter-type-list is equivalent to the parameter-type-list of an implicit declaration,
また、CWG issue 2094により、以下の文面は削除されます。
class X has no non-static data members of volatile-qualified type, and
基本的に「trivialなコピー/ムーブコンストラクタを持つ」と同じです
対象となるクラスがtrivialなコピー/ムーブ代入演算子を持つためには
- コピー/ムーブ代入演算子は
user-provided
ではない - virtual関数を持たず、virtual基本クラスも持たない
- (C++14のみ、CWG issue 2171適用前のみ)コンストラクタ/代入演算子の仮引数リストが暗黙に宣言された場合の仮引数リストと同じ
- (C++14のみ、CWG issue 2094適用前のみ)volatile修飾された型の非staticデータメンバーを持たない
が前提条件です。また、
- クラスXのクラス型とクラスの配列型の非staticデータメンバーの、コピー/ムーブに使われる代入演算子がトリビアル
非staticメンバ変数についても先の4条件が適応されます。
もし対象となるクラスが基底クラスを保つ場合は(なんか継承している場合)
- 直接の基底クラスのサブオブジェクトで使われるコピー/ムーブの代入演算子がトリビアル
このように追加条件があります。これは言い換えると、継承関係にあるクラスのうち基底クラス方向すべてのクラスが上記5条件を満たす必要があるということです。
で、例によって脳内で調べるのは限界があるのでstd::is_trivially_copy_assignable
/std::is_trivially_move_assignable
があります。
トリビアルにコピー可能なクラス(trivially copyable class)
この定義がCWG issue 1734適用前後で大きく変わっているのでそれぞれ考察していきましょう。
CWG issue 1734適用前
C++11とC++14の差分については上述の通りCWG issue 2171とCWG issue 2094によって打ち消されるので、C++11の文面を見ていきます。
N3337(C++11)
§ 9. class
6 A trivially copyable class is a class that:
— has no non-trivial copy constructors (12.8),
— has no non-trivial move constructors (12.8),
— has no non-trivial copy assignment operators (13.5.3, 12.8),
— has no non-trivial move assignment operators (13.5.3, 12.8), and
— has a trivial destructor (12.4).
A trivial class is a class that has a trivial default constructor (12.1) and is trivially copyable.
[ Note: In particular, a trivially copyable or trivial class does not have virtual functions or virtual base classes.—end note ]
CWG issue 1734適用前では、対象となるクラスがtrivially copyable classであるためには、
- trivialではないコピーコンストラクタを持たない
- trivialではないムーブコンストラクタを持たない
- trivialではないコピー代入演算子を持たない
- trivialではないムーブ代入演算子を持たない
- trivialなデストラクタを持つ
を満たす必要があります。
「trivialではない~を持たない」ってすごく回りくどいですね。「すべての~はtrivial」と解釈しましょう。
それを踏まえ、上のまとめを合体して解釈すると
- デストラクターはvirtualではない
- デストラクタと全てのコピー/ムーブ コンストラクタ/代入演算子は
user-provided
ではない - virtual関数を持たず、virtual基本クラスも持たない
さらに
- 非staticデータメンバーのデストラクターは、すべてtrivialである
- クラス型か、クラスの配列型の非staticデータメンバーをコピー/ムーブするのに使われるコンストラクターがトリビアルであること
- クラスXのクラス型とクラスの配列型の非staticデータメンバーの、コピー/ムーブに使われる代入演算子がトリビアル
非staticメンバ変数にも上記の3条件が適応されます。
もし対象となるクラスが基底クラスを保つ場合は(なんか継承している場合)
- 直接の基底クラスのデストラクターは、すべてtrivialである
- 直接の基底クラスのサブオブジェクトをコピー/ムーブするのに使われるコンストラクターがトリビアルであること
- 直接の基底クラスのサブオブジェクトで使われるコピー/ムーブの代入演算子がトリビアル
このように追加条件があります。これは言い換えると、継承関係にあるクラスのうち基底クラス方向すべてのクラスが上記6条件を満たす必要があるということです。
問題点はデストラクタが= delete
指定されていてもいいということです。
C++17 or CWG issue 1734適用後
N4659(C++17)
§ 12. class
6 A trivially copyable class is a class:
(6.1) — where each copy constructor, move constructor, copy assignment operator, and move assignment operator (15.8, 16.5.3) is either deleted or trivial,
(6.2) — that has at least one non-deleted copy constructor, move constructor, copy assignment operator, or move assignment operator, and
(6.3) — that has a trivial, non-deleted destructor (15.4).
A trivial class is a class that is trivially copyable and has one or more default constructors (15.1), all of which are either trivial or deleted and at least one of which is not deleted. [ Note: In particular, a trivially copyable or trivial class does not have virtual functions or virtual base classes.—end note ]
C++17 or CWG issue 1734適用後では、対象となるクラスがtrivially copyable classであるためには、
- 全てのコピー/ムーブ コンストラクタ/代入演算子はtrivialもしくは
= delete
指定されている - コピー/ムーブ コンストラクタ/代入演算子のうち少なくとも1つは
= delete
指定されていない - trivialで
= delete
指定されていないデストラクタを持つ
を満たす必要があります。
CWG issue 1734適用前と比べると、回りくどい書き方をやめてスッキリしましたね。また実質的な定義にも変更があります。
1つ目の「trivialもしくは= delete
指定されている」というのは冗長です。ここまで見てきたようにtrivialに= delete
指定は含まれますからね。多分2つ目と3つ目で「= delete
指定されていない」と書いたので対称性の観点からわざわざ書いてくれたんでしょう。
上のまとめを合体して解釈すると
- デストラクターはvirtualではない
- デストラクターは
= delete
指定されていない - デストラクタと全てのコピー/ムーブ コンストラクタ/代入演算子は
user-provided
ではない - virtual関数を持たず、virtual基本クラスも持たない
- コピー/ムーブ コンストラクタ/代入演算子のうち少なくとも1つは
= delete
指定されていない
さらに
- 非staticデータメンバーのデストラクターは、すべてtrivialである
- クラス型か、クラスの配列型の非staticデータメンバーをコピー/ムーブするのに使われるコンストラクターがトリビアルであること
- クラスXのクラス型とクラスの配列型の非staticデータメンバーの、コピー/ムーブに使われる代入演算子がトリビアル
非staticメンバ変数にも上記の5条件が適応されます。
もし対象となるクラスが基底クラスを保つ場合は(なんか継承している場合)
- 直接の基底クラスのデストラクターは、すべてtrivialである
- 直接の基底クラスのサブオブジェクトをコピー/ムーブするのに使われるコンストラクターがトリビアルであること
- 直接の基底クラスのサブオブジェクトで使われるコピー/ムーブの代入演算子がトリビアル
このように追加条件があります。これは言い換えると、継承関係にあるクラスのうち基底クラス方向すべてのクラスが上記8条件を満たす必要があるということです。
trivially copyable classの嬉しいこと
trivially copyable classであれば、memcpy
関数などで単純なバイト列のコピーができるようになります。
本の虫: C++0xにおけるPODの定義
つまり、memcpyでコピー出来るクラスの制限は、だいぶ緩和される。まず、コンストラクタがあってもいいし、継承していてもいい。standard-layout classである必要はない。派生クラスと基本クラスが、共に非staticなデータメンバーをもっていても構わない。アクセス指定もできる。
trivialなクラス(trivial class)
この概念はもともとPODを説明するために必要だったのですが、後述の通りPOD自体がC++20でdeprecatedになったのでこいつも忘れていいです。
そういうわけであまり重要な議論ではないので割愛したかったのですが、規格の文章だけ上でちらっと出てしまっているので引っ張り直しておきます。
N3337(C++11)
§ 9. class
A trivial class is a class that has a trivial default constructor (12.1) and is trivially copyable.
[ Note: In particular, a trivially copyable or trivial class does not have virtual functions or virtual base classes.—end note ]N4140(C++14)
§ 9. class
A trivial class is a class that has a default constructor (12.1), has no non-trivial default constructors, and is trivially copyable. [ Note: In particular, a trivially copyable or trivial class does not have virtual functions or virtual base classes.—end note ]N4659(C++17)
§ 12. class
A trivial class is a class that is trivially copyable and has one or more default constructors (15.1), all of which are either trivial or deleted and at least one of which is not deleted. [ Note: In particular, a trivially copyable or trivial class does not have virtual functions or virtual base classes.—end note ]
ただし、CWG issue 1496により、C++11/C++14の文面はC++17相当になります。
C++17でone or more default constructorsとか言い出したんですが、デフォルトコンストラクタが複数ってどういうコッチャ・・・
standard-layoutなクラス(standard-layout class)
2017年にこの記事を書き始めたときは解説する気満々だったんですが、執筆を放置していたら
先を越されました。こっち見てください。
こいつにはPODの説明以外にちゃんと役割があるので大切です。
本の虫: PODじゃなくてもいいのでは。
standard-layout classこのクラスは、オブジェクトへのポインターは、クラスの最初のデータメンバーを指し示すことを保証するものである。つまり、reinterpret_castを使って、オブジェクトへのポインターを、最初のデータメンバーのポインターにキャストした場合、ポインターは、最初のデータメンバーを指すことが保証される。
PODなクラス(pod class)
C++20からdeprecatedになる概念です。
本の虫: C++0xにおけるPODの定義
PODは、trivial classかつstandard-layout classであること。
さらに、非PODな非staticデータメンバーを持たないこと。
PODのことは忘れましょう。そういうのは考古学者に任せるべきです。
参考リンク
Working Draft, Standard for Programming Language C++
- [PDF注意]N3337: C++11 first post-publication draft
- [PDF注意]N4140: C++14 final draft
- [PDF注意]N4569: C++17 final draft
C++ Standard Core Language Issues
- 1496. Triviality with deleted and missing default constructors
- 1590. Bypassing non-copy/move constructor copying
- 1734. Nontrivial deleted copy functions
- 1928. Triviality of deleted special member functions
-
2094.
Trivial copy/move constructor for class with volatile member -
2171.
Triviality of copy constructor with less-qualified parameter
JTC1/SC22/WG21 - Papers
- N4148: Disallowing Inaccessible Operators From Trivially Copyable
C++11: Syntax and Feature(江添亮)
本の虫 - 江添亮のブログ
- 2010-05-13: PODじゃなくてもいいのでは。
- 2010-06-09: C++0xにおけるPODの定義
cpprefjp C++日本語リファレンス
Other Links about C++
- 2010-03-08: デストラクタを呼ばずに再構築 - melpon日記 - HaskellもC++もまともに扱えないへたれのページ
- 2010-05-07: C++でデストラクタを呼ばなくていい条件 - 野良C++erの雑記帳
- 2010-05-13: C++0xではPODでもコンストラクタ相当のことができる・・・? - Faith and Brave - C++で遊ぼう
- 2012-11-22: trivial class - C++と色々
- 2014-07-04: 特殊メンバ関数とコンパイラによる暗黙宣言 - yohhoyの日記
- 2016-05-21: C++ - C++11で、デストラクタ = deleteとする意味について(35601)|teratail
- 2017-06-09: @EzoeRyou@friends.nico 突然すみません。C - yumetodo - Pawoo
Other Links
追記
CWG issueのdefect reportの解釈を誤っていました。
標準C++の欠陥解決は、過去のバージョンに遡って適用される - Faith and Brave - C++で遊ぼう
によれば、defectとして採択されたCWG issueは採択された時点で処理系が適用します。つまり、defect reportとは対象となる問題が存在するすべてのISOで発行されたC++規格書のバージョンに対して適用されるものなのです。
これを踏まえて本文、とくにもっとも根幹のtrivially copyable classの定義に大幅な変更が生じました。