Share
Embed
C++14 の新機能 ライブラリ編 / new features of C++14 - Library
C++14 で追加された、各種ライブラリ機能の紹介です。
分からないなりに調べながら作ったのでいろいろ間違ってるかもです。
Miutsuru kariya
January 11, 2018
Transcript
206 slides
-
C++14 ライブラリ編 お題 演算子関数オブジェクトの強化 連想コンテナの異種比較検索 make_unique 非破壊シーケンス操作を堅固に コンパイル時整数シーケンス タプルの型指定アクセス クォート文字列ライブラリ
共有ロック タイプトレイツの短縮 integral_constant の強化 exchange ユーティリティ関数 4 -
C++14 ライブラリ編 お題 標準ライブラリのユーザ定義リテラル ヌル前方イテレータ functionalのconstexpr対応 chronoのconstexpr対応 complexのconstexpr対応 ユーティリティのconstexpr対応 コンテナのconstexpr対応
非メンバ関数の cbegin と cend rand とその仲間の非推奨化 gets の廃止 5 -
演算子関数オブジェクトの強化 8 演算子関数オブジェクトって何の事よ? ⇓ 標準ライブラリにある、std::less とか std::equal_to とかってヤツの事 原題は operator
functor なんだけど、どう訳せばい いか分かんなかったので… -
演算子関数オブジェクトの強化 導入の背景 12 2. 二項演算子の引数が同じ 型ってのはどうなのよ std::string と文字列リテラルの比較、operator> なら 直接できるのに
std::greater<std::string> だと文字 列リテラルに対応する一時std::stringオブジェクトが 作られるツラい… -
演算子関数オブジェクトの強化 対応 16 デフォルトテンプレート引数を void にした。 template<typename T = void>
struct greater { constexpr bool operator()(const T& x, const T& y) const { return x > y; } }; 今まで void は有効な型引数じゃなかったので、後方互換性 保つのにちょうど良い(voidの参照とか無いので) -
演算子関数オブジェクトの強化 対応 18 void特殊化を以下のようにした。 template<> struct greater<void> { template<typename T,
typename U> constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) > std::forward<U>(u)) { return std::forward<T>(t) > std::forward<U>(u); } }; 引数は完全転送に、戻り値型はdecltypeになってる。 -
連想コンテナの異種比較検索 N2820 Adding heterogeneous comparison lookup to associative containers http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2820.pdf
N2882 Adding heterogeneous comparison lookup to associative containers for TR2 (Rev 1) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2882.pdf N3465 Adding heterogeneous comparison lookup to associative containers for TR2 (Rev 2) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3465.pdf N3657 Adding heterogeneous comparison lookup to associative containers (rev 4) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3657.htm 21 -
連想コンテナの異種比較検索 導入の背景 24 binary_search のシグネチャ template<class ForwardIterator, class T, class
Compare> bool binary_search(ForwardIterator first, ForwardIterator last, const T& value, Compare comp); *first と value は comp で比較できれば同じ型じゃなくてもい い 関係ないけど戻り値 bool だから使い道めっさ限定されるよな… -
連想コンテナの異種比較検索 導入の背景 25 連想コンテナの find のシグネチャ iterator find(const key_type& x);
const_iterator find(const key_type& x) const; x は key_type じゃないとダメ -
連想コンテナの異種比較検索 対応 29 今までと変わらないヤツ std::set<std::string> s1; 新しくできたイケてるヤツ std::set<std::string, std::less<>> s2;
テンプレート引数に渡した比較関数オブジェ クトが異種比較できるヤツだった場合に限っ て、イケてるヤツになる。 -
連想コンテナの異種比較検索 対応 32 追加となるメンバ関数テンプレート(Kはテンプレートパラメータ) iterator find(const K& k); const_iterator find(const
K& k) const; size_type count(const K& k); iterator lower_bound(const K& k); const_iterator lower_bound(const K& k) const; iterator upper_bound(const K& k); const_iterator upper_bound(const K& k) const; pair<iterator, iterator> equal_range(const K& k); pair<const_iterator, const_iterator> equal_range(const K& k) const; -
make_unique 標準ライブラリに入れる利点 40 2. make_sharedと同じ利点が2つ ある。 • unique_ptr作る時に型名を2回書 かなくて済む。 •
引数の評価順が未規定であるこ とに由来するメモリリークを起こさ ずに済む。 -
make_unique 標準ライブラリに入れる利点 41 make_uniqueが無い場合 auto p = std::unique_ptr<int>(new int(42)); make_uniqueがある場合
auto p = std::make_unique<int>(42); 特に型が長い場合はめんどっちい… -
make_unique 標準ライブラリに入れる利点 42 メモリリークするかもケース f(unique_ptr<X>(new X), unique_ptr<Y>(new Y)); 毎度おなじみのヤツ。 例えば、new
Xが実行された後unique_ptr<X>が作 られる前にnew Yが実行されて、かつ、そこで例外 が発生するとnew Xで割り当てられたメモリがリー クする。 -
make_unique シグネチャ 45 1.単体オブジェクトの場合 template<typename T, typename... Args> unique_ptr<T> make_unique(Args&&...
args); 2.サイズ指定なしの配列オブジェクトの場合 template<typename T> unique_ptr<T> make_unique(size_t n); 3.サイズ指定ありの配列オブジェクトの場合(使えない) template<typename T, typename... Args> unspecified make_unique(Args&&... args) = delete; -
make_unique 設計上の考慮点 47 コンストラクタは()と{}のどっちで呼 び出される? ⇓ ()で呼び出される。 • make_sharedと合わせた方がいい。 •
make_unique<X>(args...)って書く ので、()の方がしっくりくる。 -
非破壊シーケンス操作を 堅固に N3607 Making non-modifying sequence operations more robust http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3607.html
N3671 Making non-modifying sequence operations more robust: Revision 2 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3671.html 50 -
非破壊シーケンス操作を堅固 に 導入の背景 53 std::vector<int> v1{ 1, 2, 3 };
std::vector<int> v2{ 4, 5 }; auto b = std::equal(v1.begin(), v1.end(), v2.begin()); v2 の方が短いので、ヤバイ… -
非破壊シーケンス操作を堅固 に 対応 56 std::mismatch の追加オーバーロード template<typename InputIterator1, typename InputIterator2>
pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); template<typename InputIterator1, typename InputIterator2, typename BinaryPredicate> pair<InputIterator1, InputIterator2> mismatch(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred); -
非破壊シーケンス操作を堅固 に 対応 57 std::equal の追加オーバーロード template<typename InputIterator1, typename InputIterator2>
bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); template<typename InputIterator1, typename InputIterator2, typename BinaryPredicate> bool equal(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred); -
非破壊シーケンス操作を堅固 に 対応 58 std::is_permutation の追加オーバーロード template<typename InputIterator1, typename InputIterator2>
bool is_permutation(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2); template<typename InputIterator1, typename InputIterator2, typename BinaryPredicate> bool is_permutation(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred); -
非破壊シーケンス操作を堅固 に 対応 59 ちなみに、equalとis_permutation は引数がランダムアクセスイテ レータの場合、 last1 - first1
!= last2 - first2 の時は本体を比較せずに false を返す。 -
コンパイル時整数シーケン ス N3493 Compile-time integer sequences http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3493.html N3658 Compile-time integer
sequences http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3658.html 60 -
コンパイル時整数シーケンス 導入の背景 63 関数パラメータパックの各要素に関数を適用してタプルで返 却する例 template<typename F, typename... Args> std::tuple<Args...>
g(F&& f, Args&&... args) { return std::make_tuple(f(std::forward<Args>(args))...); } 関数パラメータパックだと割と簡単 -
コンパイル時整数シーケンス 導入の背景 64 タプルの各要素に関数を適用してタプルで返却する(コンパ イルエラーな)例 template<typename F, typename... Args> std::tuple<Args...>
g(F&& f, const std::tuple<Args...>& t) { return std::make_tuple(f(std::forward<Args>(t))...); } いや、t は関数パラメータパックじゃないので、こうは書けな い… -
コンパイル時整数シーケンス 導入の背景 65 タプルの各要素に関数を適用してタプルで返却する(再帰を 使った)例 template<std::size_t I, typename F, typename...
T, typename... U> std::enable_if_t<sizeof...(T) == I, std::tuple<T...>> g_impl(F&& f, const std::tuple<T...>&, U&&... args) { return std::make_tuple(f(std::forward<U>(args))...); } template<std::size_t I, typename F, typename... T, typename... U> std::enable_if_t<sizeof...(T) != I, std::tuple<T...>> g_impl(F&& f, const std::tuple<T...>& t, U&&... args) { return g_impl<I + 1>(std::forward<F>(f), t, std::forward<U>(args)..., std::get<I>(t)); } template<typename F, typename... T> std::tuple<T...> g(F&& f, const std::tuple<T...>& t) { return g_impl<0>(std::forward<F>(f), t); } 何とか頑張って再帰を使って関数パラメータパックに変換し てから適用してみました。多分正しく動くと思うけどツラい… -
コンパイル時整数シーケンス 導入の背景 67 std::size_t... 型の 0, 1, 2...N-1 という非 型テンプレートパラメータパック
I がある と、可変長タプル t は std::get<I>(t)... と書くと再帰無しで展開できる。 関係ないけどこういうこと考えられるヤツってすごい… -
コンパイル時整数シーケンス 導入の背景 68 タプルの各要素に関数を適用してタプルで返却する(index tuple idiomを使った)例 template<typename F, typename... T,
std::size_t... I> td::tuple<T...> g_impl(F&& f, const std::tuple<T...>& t, ????) { return std::make_tuple(f(std::get<I>(t))...); } template<typename F, typename... T> std::tuple<T...> g(F&& f, const std::tuple<T...>& t) { return g_impl(std::forward<F>(f), t, ????); } I と ???? さえうまく作れば割と簡単に書けそう… -
コンパイル時整数シーケンス 対応 72 任意の整数型 T の整数シーケンスを表すクラス template<typename T, T... I>
struct integer_sequence { typedef T value_type; static constexpr size_t size() noexcept { return sizeof...(I); } }; I は T 型の整数シーケンス -
コンパイル時整数シーケンス 対応 73 integer_sequence を簡単に作るためのクラス template<typename T, T N> using
make_integer_sequence = integer_sequence<T, 0, 1, .... , N - 1>; 0, 1, .... , N - 1 の部分はうまい事やってくれる。 ちなみに、再帰を使って作る -
コンパイル時整数シーケンス 対応 74 ちなみに、0, 1, .... , N - 1
の部分は再帰を使って作 ることができるが、普通にやると N 回再帰してしま う。(提案の参照実装ではそうなっていた) しかし、再帰深度に敏感なボレロ村上さんが対数 オーダーで作成できるから、規格で対数オーダー 以下とするように提案した。 すごいぞ我らがボレロ村上!!!1! http://boleros.hateblo.jp/entry/20130127/1359292468 -
コンパイル時整数シーケンス 対応 75 size_t 型 T の整数シーケンスを表すクラス template<size_t... I> using
index_sequence = integer_sequence<size_t, I...>; I は size_t 型の整数シーケンス size_t 型の整数シーケンスが一番よく使うので、別 名を定義しておく。(index、つまり添え字) -
コンパイル時整数シーケンス 対応 76 index_sequence を簡単に作るためのクラス template<size_t N> using make_index_sequence =
make_integer_sequence<size_t, N>; 0, 1, 2, .... , N - 1 の index_sequence を作ってくれる。 -
コンパイル時整数シーケンス 対応 77 index_sequence を簡単に作るためのクラスその2 template<class... T> using index_sequence_for =
make_index_sequence<sizeof...(T)>; T の数に応じた index_sequence を作ってくれる。 -
コンパイル時整数シーケンス 使用例 79 タプルの各要素に関数を適用してタプルで返却する (index_sequenceを使った)例 template<typename F, typename... T, std::size_t...
I> std::tuple<T...> g_impl(F&& f, const std::tuple<T...>& t, std::index_sequence<I...>) { return std::make_tuple(f(std::get<I>(t))...); } template<typename F, typename... T> std::tuple<T...> g(F&& f, const std::tuple<T...>& t) { return g_impl(std::forward<F>(f), t, std::index_sequence_for<T...>{}); } 割と簡単…かな…? -
タプルの型指定アクセス N3404 Tuple Tidbits http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3404.html N3584 Wording for Addressing Tuples
by Type http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3584.html N3670 Wording for Addressing Tuples by Type: Revision 2 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3670.html 80 -
タプルの型指定アクセス 導入の背景 83 例えば、 tuple<employee_id, salary, office> を返す関数 get_employee_info(...) があった時、
get<2>(get_employee_info(...)) より get<office>(get_employee_info(...)) の方が分かりやすい (場所が変わっても大丈夫) -
タプルの型指定アクセス シグネチャ 87 タプル // 参照バージョン template <class T, class...
Types> constexpr T& get(tuple<Types...>& t) noexcept; // const参照バージョン template <class T, class... Types> constexpr const T& get(const tuple<Types...>& t) noexcept; // 右辺値参照バージョン template <class T, class... Types> constexpr T&& get(tuple<Types...>&& t) noexcept; -
タプルの型指定アクセス シグネチャ 88 ペア template <class T, class U> constexpr
T& get(pair<T, U>& p) noexcept; template <class T, class U> constexpr const T& get(const pair<T, U>& p) noexcept; template <class T, class U> constexpr T&& get(pair<T, U>&& p) noexcept; template <class T, class U> constexpr T& get(pair<U, T>& p) noexcept; template <class T, class U> constexpr const T& get(const pair<U, T>& p) noexcept; template <class T, class U> constexpr T&& get(pair<U, T>&& p) noexcept; -
タプルの型指定アクセス 90 余談 getが非メンバ関数なのは、メンバ関数だと呼び出 す時にtemplateキーワードが必要になるから std::tuple<std::string, int> t = {
"the Answer", 42 }; std::cout << t.template get<1> << '¥n'; -
クォート文字列ライブラリ N3431 Quoted Strings Library Proposal http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3431.html N3570 Quoted Strings
Library Proposal (Revision 1) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3570.html N3654 Quoted Strings Library Proposal (Revision 2) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3654.html 91 -
クォート文字列ライブラリ 導入の背景 94 アカン例 std::stringstream ss; std::string original = "foolish
me"; std::string round_trip; ss << original; ss >> round_trip; std::cout << original; // outputs: foolish me std::cout << round_trip; // outputs: foolish assert(original == round_trip); // assert will fire 提案ペーパーより -
クォート文字列ライブラリ 対応 97 対応後の例 std::stringstream ss; std::string original = "foolish
me"; std::string round_trip; ss << quoted(original); ss >> quoted(round_trip); std::cout << original; // outputs: foolish me std::cout << round_trip; // outputs: foolish me assert(original == round_trip); // assert will not fire 提案ペーパーより -
クォート文字列ライブラリ 対応 99 iomanip ヘッダに以下の関数を追加 // 文字列リテラル等出力用 template <class charT>
T11 quoted(const charT* s, charT delim = charT('"'), charT escape = charT('¥¥')); // basic_string出力用 template <class charT, class traits, class Allocator> T12 quoted(const basic_string<charT, traits, Allocator>& s, charT delim = charT('"'), charT escape = charT('¥¥')); // basic_string入力用 template <class charT, class traits, class Allocator> T13 quoted(basic_string<charT, traits, Allocator>& s, charT delim = charT('"'), charT escape = charT('¥¥')); T11、T12、T13 は実装依存のナゾの型 -
共有ロック 101 N2094 Multithreading API for C++0X - A Layered
Approach http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2094.html N2406 Mutex, Lock, Condition Variable Rationale http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2406.html N3427 Shared locking in C++ http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3427.html N3568 Shared locking in C++ Revision 1 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3568.html N3659 Shared locking in C++ Revision 2 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3659.html N3891 A proposal to rename shared_mutex to shared_timed_mutex http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3891.htm -
共有ロック 対応 108 共有ロックをサポートするミューテックス class shared_timed_mutex; 通常の排他ロックの操作用メンバ関数一式 に加え、そっくりの共有ロックの操作用メンバ 関数一式を備える。 なお、timed
の名前の通りタイムアウト付き のロック操作用メンバ関数も備える。 -
共有ロック 対応 109 shared_timed_mutexのメンバ関数 // デフォルトコンストラクタ・デストラクタ shared_timed_mutex(); ~shared_timed_mutex(); // コピーコンストラクタ・コピー代入演算子(コピーできない)
shared_timed_mutex(const shared_timed_mutex&) = delete; shared_timed_mutex& operator=(const shared_timed_mutex&) = delete; // ちなみにムーブもできない -
共有ロック 対応 110 shared_timed_mutexのメンバ関数 // 排他ロック用 void lock(); bool try_lock();
void unlock(); // 共有ロック用 void lock_shared(); bool try_lock_shared(); void unlock_shared(); -
共有ロック 対応 111 shared_timed_mutexのメンバ関数 // 排他ロック用(タイムアウト付き) template <class Rep, class
Period> bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); template <class Clock, class Duration> bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); // 共有ロック用(タイムアウト付き) template <class Rep, class Period> bool try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time); template <class Clock, class Duration> bool try_lock_shared_until(const chrono::time_point<Clock, Duration>& abs_time); -
共有ロック 対応 112 注意 • shared_timed_mutex はリカーシブミューテックスで はないので、自分が既に排他ロックや共有ロックを 持ってる場合に更にロックを取得しようとした場合 の挙動はUB(未定義動作)。
• また、共有ロックを排他ロックに格上げしたり排他 ロックを共有ロックに格下げしたりもできない。 -
共有ロック 対応 114 共有ロックをサポートするロックオブジェクト template<typename Mutex> class shared_lock; unique_lock の共有モード版。Mutex
につい て呼び出すメンバ関数がshared版になるだけ。 ただし、自分のメンバ関数名はunique_lockと 一緒。(つまりshared_lockもLockable) -
共有ロック 対応 115 shared_lock のメンバ関数 // デフォルトコンストラクタ・デストラクタ shared_lock() noexcept; ~shared_lock();
// ミューテックスを用いたコンストラクタ explicit shared_lock(mutex_type& m); // 共有ロックするぞ shared_lock(mutex_type& m, defer_lock_t) noexcept; // あとで共有ロックするぞ shared_lock(mutex_type& m, try_to_lock_t); // 試しに共有ロックしてみるぞ // (できるとは言ってない) shared_lock(mutex_type& m, adopt_lock_t); //既に共有ロック持ってるぞ -
共有ロック 対応 116 shared_lock のメンバ関数 // タイムアウト付きコンストラクタ(共有ロックとれてないかも) template <class Clock,
class Duration> shared_lock(mutex_type& m, const chrono::time_point<Clock, Duration>& abs_time); template <class Rep, class Period> shared_lock(mutex_type& m, const chrono::duration<Rep, Period>& rel_time); -
共有ロック 対応 117 shared_lock のメンバ関数 // コピーコンストラクタ・コピー代入演算子(コピーできない) shared_lock(shared_lock const&) =
delete; shared_lock& operator=(shared_lock const&) = delete; // ムーブコンストラクタ・ムーブ代入演算子(ムーブできる) shared_lock(shared_lock&& u) noexcept; shared_lock& operator=(shared_lock&& u) noexcept; // ムーブ代入演算子の noexcept は規格書のバグだと思うんだよなぁ… -
共有ロック 対応 118 shared_lock のメンバ関数 // 共有ロック・アンロック void lock(); bool
try_lock(); void unlock(); // 共有ロック(タイムアウト付き) template <class Rep, class Period> bool try_lock_for(const chrono::duration<Rep, Period>& rel_time); template <class Clock, class Duration> bool try_lock_until(const chrono::time_point<Clock, Duration>& abs_time); -
共有ロック 対応 119 shared_lock のメンバ関数 // 共有ロック状態取得 bool owns_lock() const
noexcept; explicit operator bool () const noexcept; // その他メンバ関数 void swap(shared_lock& u) noexcept; // 交換 mutex_type* release() noexcept; // ミューテックスの解放 mutex_type* mutex() const noexcept; // ミューテックスの取得(解放はしない) -
共有ロック 対応 120 shared_lock のメンバ型 typedef Mutex mutex_type; // 保持しているミューテックスの型
shared_lock 関連の非メンバ関数 template <class Mutex> void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept; -
共有ロック shared_timed_mutex の使い方 123 排他ロックの場合、今までのmutexやtimed_mutexとか と同じくlock_guardやunique_lockと一緒に使えばよい std::shared_timed_mutex stm; void f()
{ std::lock_guard<std::shared_timed_mutex> lg(stm); クリティカルセクション(他の共有ロックで保護された箇所も含めて同時実行不可) } // 自動で開放 -
共有ロック shared_timed_mutex の使い方 124 共有ロックの場合、unique_lockの替わりにshared_lock と一緒に使えばよい std::shared_timed_mutex stm; void g()
{ std::shared_lock<std::shared_timed_mutex> sl(stm); クリティカルセクション(ただし、共有ロック同士なら同時実行可) } // 自動で開放 -
共有ロック shared_timed_mutex の使い方 125 複数のshared_timed_mutex使うときは、当然順序に気を付けな いとデッドロックするぞ。 提案ペーパーにあったコピー代入演算子のアカン例 A& operator=(const A&
a) { if (this != &a) { std::unique_lock<std::shared_timed_mutex> lhs(mut_); std::shared_lock<std::shared_timed_mutex> rhs(a.mut_); // Wrong! Deadlock! // Assign data ... } return *this; } a = b と b = a を同時に実行するとデッドロック! -
共有ロック shared_timed_mutex の使い方 126 shared_lockと一緒に使えばそれ自体がLockableになるからlock 関数で使えるぞ。 提案ペーパーにあったコピー代入演算子のマトモな例 A& operator=(const A&
a) { if (this != &a) { std::unique_lock<std::shared_timed_mutex> lhs(mut_, defer_lock); std::shared_lock<std::shared_timed_mutex> rhs(a.mut_, defer_lock); std::lock(lhs, rhs); // Assign data ... } return *this; } -
共有ロック shared_timed_mutex の使い方 127 shared_lockと一緒に使えばLockableになるから条件変数でも共 有ロックが使えるぞ。ただし、condition_variable_any の方で。 提案ペーパーにあった条件変数の例 std::shared_timed_mutex mut;
std::condition_variable_any cv; void foo() { std::shared_lock<std::shared_timed_mutex> sl(mut); // 共有ロック中 cv.wait(sl, []{ return 条件整った?; }); // 条件整うまで待つぞ // 共有ロック中 } 起こす方は cv.notify_all() でも使ってね -
タイプトレイツの短縮 対応 135 実際の定義はちょー簡単でこんな感じ template<typename T> using remove_reference_t = typename
remove_reference<T>::type; エイリアステンプレート使ってるだけ (でも全部で24個もあるので自分で定義するのは結構めんどう…) -
タイプトレイツの短縮 対応 136 CV系 template <class T> using remove_const_t =
typename remove_const<T>::type; template <class T> using remove_volatile_t = typename remove_volatile<T>::type; template <class T> using remove_cv_t = typename remove_cv<T>::type; template <class T> using add_const_t = typename add_const<T>::type; template <class T> using add_volatile_t = typename add_volatile<T>::type; template <class T> using add_cv_t = typename add_cv<T>::type; -
タイプトレイツの短縮 対応 137 参照系 template <class T> using remove_reference_t =
typename remove_reference<T>::type; template <class T> using add_lvalue_reference_t = typename add_lvalue_reference<T>::type; template <class T> using add_rvalue_reference_t = typename add_rvalue_reference<T>::type; 符号系 template <class T> using make_signed_t = typename make_signed<T>::type; template <class T> using make_unsigned_t = typename make_unsigned<T>::type; -
タイプトレイツの短縮 対応 138 配列系 template <class T> using remove_extent_t =
typename remove_extent<T>::type; template <class T> using remove_all_extents_t = typename remove_all_extents<T>::type; ポインタ系 template <class T> using remove_pointer_t = typename remove_pointer<T>::type; template <class T> using add_pointer_t = typename add_pointer<T>::type; -
タイプトレイツの短縮 対応 139 アライン系 template <size_t Len, size_t Align =
デフォルトアライン> using aligned_storage_t = typename aligned_storage<Len, Align>::type; template <size_t Len, class... Types> using aligned_union_t = typename aligned_union<Len, Types...>::type; 条件系 template <bool b, class T = void> using enable_if_t = typename enable_if<b, T>::type; template <bool b, class T, class F> using conditional_t = typename conditional<b, T, F>::type; -
タイプトレイツの短縮 対応 140 その他変換系 template <class T> using decay_t =
typename decay<T>::type; template <class... T> using common_type_t = typename common_type<T...>::type; template <class T> using underlying_type_t = typename underlying_type<T>::type; template <class T> using result_of_t = typename result_of<T>::type; タプル系 template <size_t I, class T> using tuple_element_t = typename tuple_element<I, T>::type; -
integral_constant の強化 導入の背景 146 暗黙変換される場所の場合 // 普通の書き方 std::enable_if_t<std::is_arithmetic<T>::value> // 暗黙変換を使った書き方
std::enable_if_t<std::is_arithmetic<T>{}> いや、そもそも上の書き方でいいんじゃないかと思うんですが… -
integral_constant の強化 導入の背景 147 暗黙変換されない場所の場合(どこ?) // 普通の書き方 auto b =
std::is_arithmetic<T>::value; // ユーザ定義変換を無理やり使った書き方 auto b = static_cast<bool>(std::is_arithmetic<T>{}); いや、そもそも(ry -
integral_constant の強化 対応 150 以下のメンバ関数を追加 constexpr value_type operator()() const noexcept
{ return value; } いや、そもそも(ry -
integral_constant の強化 対応 151 暗黙変換されない場所の場合(どこ?) // 普通の書き方 auto b =
std::is_arithmetic<T>::value; // ユーザ定義変換を無理やり使った書き方 auto b = static_cast<bool>(std::is_arithmetic<T>{}); // 関数呼び出し演算子を使った書き方 <- NEW!!! auto b = std::is_arithmetic<T>{}(); いや、そもそも(ry -
exchange ユーティリティ関 数 N3511 exchange() utility function http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3511.html N3608 exchange()
utility function, revision 2 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3608.html N3668 exchange() utility function, revision 3 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3668.html 153 -
exchange ユーティリティ関数 対応 159 以下のユーティリティ関数を<utility> ヘッダに追加。 template <class T, class
U=T> T exchange(T& obj, U&& new_val); obj に new_val を設定すると共に、obj の古 い値を返す。ただし、処理はアトミックじゃな い。 -
標準ライブラリのユーザ定義 リテラル N3402 User-defined Literals for Standard Library Types http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3402.pdf
N3468 User-defined Literals for Standard Library Types (version 2) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3468.pdf N3531 User-defined Literals for Standard Library Types (version 3) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3531.pdf N3642 User-defined Literals for Standard Library Types(part 1 - version 4) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3642.pdf N3660 User-defined Literals for std::complex, part 2 of UDL for Standard Library Types (version 4) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3660.pdf N3779 User-defined Literals for std::complex, part 2 of UDL for Standard Library Types (version 5) http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3779.pdf 161 -
標準ライブラリのユーザ定義リ テラル 対応 166 一般規則 • ユーザ定義リテラル用のインラ イン名前空間を機能グループ 毎に作ろう •
全部のユーザ定義リテラル用 のインライン名前空間も作ろう -
標準ライブラリのユーザ定義リ テラル 対応 168 std::basic_string namespace std { inline namespace
literals { inline namespace string_literals { string operator "" s(const char* str, size_t len); u16string operator "" s(const char16_t* str, size_t len); u32string operator "" s(const char32_t* str, size_t len); wstring operator "" s(const wchar_t* str, size_t len); } } } -
標準ライブラリのユーザ定義リ テラル 対応 169 std::basic_stringの使用例 using namespace std::literals::string_literals; // std::string_literals、
// std::literalsでも可 // (stdはやめようね…) auto s1 = "Hello, UDL"s; // std::string auto s2 = u8"ユーザ定義リテラルマジ卍"s; // これもstd::string auto s3 = u"これはUTF-16文字列"s; // std::u16string auto s4 = U"オレUTF-32文字列"s; // std::u32string auto s5 = L"わいナゾのワイド文字列"s; // std::wstring これ結構便利じゃないですか? -
標準ライブラリのユーザ定義リ テラル 対応 170 std::chrono::duration // 整数系 namespace std {
inline namespace literals { inline namespace chrono_literals { constexpr chrono::hours operator "" h (unsigned long long); // 時 constexpr chrono::minutes operator "" min(unsigned long long); // 分 constexpr chrono::seconds operator "" s (unsigned long long); // 秒 constexpr chrono::milliseconds operator "" ms (unsigned long long); // ミリ秒 constexpr chrono::microseconds operator "" us (unsigned long long); // マイクロ秒 constexpr chrono::nanoseconds operator "" ns (unsigned long long); // ナノ秒 } } } -
標準ライブラリのユーザ定義リ テラル 対応 171 std::chrono::duration // 浮動小数点数系 namespace std {
inline namespace literals { inline namespace chrono_literals { constexpr chrono::duration<unspecified, ratio<3600,1>> operator "" h (long double); // 時 constexpr chrono::duration<unspecified, ratio<60,1>> operator "" min(long double); // 分 constexpr chrono::duration<unspecified> operator "" s (long double); // 秒 constexpr chrono::duration<unspecified, milli> operator "" ms (long double); // ミリ秒 constexpr chrono::duration<unspecified, micro> operator "" us (long double); // マイクロ秒 constexpr chrono::duration<unspecified, nano> operator "" ns (long double); // ナノ秒 } } } -
標準ライブラリのユーザ定義リ テラル 対応 172 std::chrono::duration // std::chrono でも使えるようにしておく namespace std
{ namespace chrono { using namespace literals::chrono_literals; } } -
標準ライブラリのユーザ定義リ テラル 対応 173 std::chrono::durationの使用例 using namespace std::literals::chrono_literals; // std::chrono_literals、
// std::literalsでも可 // (stdはやめようね…) auto constexpr aday = 24h; // std::chrono::hours auto constexpr lesson = 45min; // std::chrono::minutes auto constexpr halfanhour = 0.5h; // std::chrono::duration<unspecified, ratio<3600,1>> -
標準ライブラリのユーザ定義リ テラル 対応 174 std::complex namespace std { inline namespace
literals { inline namespace complex_literals { constexpr complex<long double> operator""il(long double); constexpr complex<long double> operator""il(unsigned long long); constexpr complex<double> operator""i(long double); constexpr complex<double> operator""i(unsigned long long); constexpr complex<float> operator""if(long double); constexpr complex<float> operator""if(unsigned long long); } } } -
標準ライブラリのユーザ定義リ テラル 対応 175 std::complexの使用例 using namespace std::literals::complex_literals; // std::complex_literals、
// std::literalsでも可 // (stdはやめようね…) auto constexpr c1 = 1 + 2il; // std::complex<long double> auto constexpr c2 = 2.0 + 4.0i; // std::complex<double> auto constexpr c3 = 0.5F + 1.0if; // std::complex<float> -
標準ライブラリのユーザ定義リ テラル 対応 176 注意 std::complex も含めて、これらの接尾辞 は小文字しかダメ ダメな例 auto
constexpr c = 1.0L + 2.0IL; LはいいけどILっていう接尾辞は無いツラい… -
functionalのconstexpr対応 N3749 Constexpr Library Additions: functional http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3749.htm N3789 Constexpr Library
Additions: functional http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3789.htm 183 -
chronoのconstexpr対応 N3229 Constexpr Library Additions: chrono http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3229.html N3303 Constexpr Library
Additions: chrono, v2 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3303.html N3469 Constexpr Library Additions: chrono, v3 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3469.html 184 -
complexのconstexpr対応 N3228 Constexpr Library Additions: complex http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3228.html N3302 Constexpr Library
Additions: complex, v2 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3302.html 185 -
ユーティリティのconstexpr 対応 N3231 Constexpr Library Additions: support/utilities http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3231.html N3305 Constexpr
Library Additions: utilities, v2 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3305.html N3471 Constexpr Library Additions: utilities, v3 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3471.html 186 -
コンテナのconstexpr対応 N3304 Constexpr Library Additions: containers http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3304.html N3470 Constexpr Library
Additions: containers, v2 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3470.html 187 -
非メンバ関数の cbegin と cend LWG Issue 2128. Absence of global
functions cbegin/cend http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#2128 188 -
非メンバ関数の cbegin と cend 導入の背景 190 非メンバ関数の cbegin と cend
無いのって規格のバグ やろ? -
非メンバ関数の cbegin と cend 対応 192 せやな。 ついでに rbegin とか
crbegin とかも追加しよ。 -
非メンバ関数の cbegin と cend 対応 193 以下の非メンバ関数を追加 template <class C>
auto cbegin(const C& c) -> decltype(std::begin(c)); template <class C> auto cend(const C& c) -> decltype(std::end(c)); template <class C> auto rbegin(C& c) -> decltype(c.rbegin()); template <class C> auto rbegin(const C& c) -> decltype(c.rbegin()); template <class C> auto rend(C& c) -> decltype(c.rend()); template <class C> auto rend(const C& c) -> decltype(c.rend()); template <class T, size_t N> reverse_iterator<T*> rbegin(T (&array)[N]); template <class T, size_t N> reverse_iterator<T*> rend(T (&array)[N]); template <class E> reverse_iterator<const E*> rbegin(initializer_list<E> il); template <class E> reverse_iterator<const E*> rend(initializer_list<E> il); template <class C> auto crbegin(const C& c) -> decltype(std::rbegin(c)); template <class C> auto crend(const C& c) -> decltype(std::rend(c)); 意外といっぱいあった… -
N3547 Three <random>-related Proposals http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3547.pdf N3742 Three <random>-related Proposals, v2
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3742.pdf N3775 Deprecating rand() and Friends http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3775.pdf N3841 Discouraging rand() in C++14 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3841.pdf N3924 Discouraging rand() in C++14, v2 http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3924.pdf 195 -
rand とその仲間の非推奨化 背景 199 random_shuffle も rand 使ってる かもしれないし、shuffle あるから
一緒に非推奨化にしてもいいや ろ…