読者です 読者をやめる 読者になる 読者になる

C++1z INVOKEコンセプトに従った関数呼び出しをするinvoke()関数

C++

C++11から入ったstd::mem_fn()関数、std::bind()関数、std::result_ofメタ関数などは、どれもINVOKEコンセプトという仕様のもとに定義されています。 これらの機能は、関数オブジェクトをただ呼び出すだけでなく、 メンバ関数ポインタ + レシーバー + 引数を…

C++1z 配列版unique_ptrの型変換

C++

C++14まで、以下のコードは不適格(コンパイルエラー)でした: unique_ptr<Foo const * const []> ptr1(new Foo*[10]); Foo const * ptr = ptr1[9]; C++1zでは、このような型変換を許可するために、unique_ptrの配列に対する特殊化バージョンに、変換コンストラクタや変換代入演算子</foo>…

C++1z void_t

C++

C++1zから、SFINAEによる「型に対して特性の操作ができるか」を判定するメタ関数の定義を容易にするために、void_tというパラメータで任意の数の型を受け取ってなにもせずvoidを返す型が定義されます。 // <type_traits> namespace std { template <class...> using void_t = void; </class...></type_traits>…

C++1z コンテナのコピー・ムーブ、swap操作にnoexceptを追加

C++

C++14までコンテナのnoexceptは最小限でしたが、C++1zではアロケータのコピーやムーブが例外を投げる可能性があるかどうかに基づいて、noexceptが追加されます。これで、標準ライブラリを使用したプログラムがより強い例外安全性を保証できるようになります。…

C++1z 標準イテレータ全般とarrayの変更操作にconstexprを追加

C++

C++1zでは、以下の機能にconstexprが付きます。 <iterator> std::advance()関数 std::distance()関数 std::next()関数 std::prev()関数 std::reverse_iteratorクラスのメンバ関数、非メンバ関数すべて std::move_iteratorクラスのメンバ関数、非メンバ関数すべて コン</iterator>…

C++1z 連想コンテナ用のデフォルトの順序付け

C++

この機能はC++1z入りが取り消されました。 mapやsetのキーとなる型はデフォルトで、operator<で比較できる必要があります。連想コンテナのキーにできるようにするために、ユーザー定義型にoperator<を定義することもありますが、その比較演算を連想コンテナ…

C++1z 連想コンテナの接合

C++

C++1zでは、2つの連想コンテナを接合(splice)する機能が入ります。対象は、map、set、unordered_map、unordered_setとそれらのmulti版すべてです。 まず、特定の要素を抽出する機能として、extract()メンバ関数が追加されます。 node_type extract(const_ite…

C++1z mapとunordered_mapに、挿入失敗時の動作を規定した新たなメンバ関数を追加

C++

一意なキーを持つstd::mapとstd::unordered_mapに対して、2種類のメンバ関数が追加されます。対象には、std::multimapやstd::unordered_multimapおよび集合コンテナは含みません。 try_emplace()メンバ関数 : 挿入失敗時に、与えられたパラメータargs...を変…

C++1z ロケール依存なし、フォーマット解析なしの高速な文字列・数値変換

C++

C++1zから、低レイヤーの文字列・数値間の変換関数が導入されます。これは、ハイパフォーマンスな文字列処理をするための基礎を提供することを目的としています。 数値から文字列への変換はto_chars()、文字列から数値への変換はfrom_chars()という関数です…

C++1z 最大公約数と最小公倍数

C++

C++1zから、2つの値の最大公約数(Greatest common divisor)を求めるgcd()関数と、最小公倍数(Least common multiple)を求めるlcm()関数が導入されます。 これらの関数は、<cmath>ではなく数値計算用のC++ヘッダ<numeric>で定義されます。bool以外の整数型ならなんでも扱えま</numeric></cmath>…

C++1z タプルを任意の型のオブジェクトに変換するmake_from_tuple関数

C++

タプルを展開して関数呼び出しするapply()関数の導入に合わせて、タプルを任意の型に変換するmake_from_tuple()関数が導入されます。 apply()関数ではオブジェクトの構築までカバーができない(コンストラクタを呼び出せない)ので、そのコーナーケースをカバ…

C++1z タプルを展開して関数呼び出しするapply関数

C++

C++1zから、タプルを引数列に変換して関数適用するapply()関数が入ります。これは、C++14で追加されたコンパイル時整数シーケンスを使用した最初の標準ライブラリ実装になります。 #include <iostream> #include <tuple> #include <string> void f(int a, double b, std::string c) { </string></tuple></iostream>…

C++1z ランダムサンプリングアルゴリズム

C++

C++1zでは<algorithm>ヘッダに、範囲の中から指定された個数の要素をランダムに抽出するsample()アルゴリズムが定義されます。 #include <iostream> #include <string> #include <iterator> #include <random> #include <algorithm> int main() { const std::string input = "abcdef"; // inputから3要素を無作為抽出す</algorithm></random></iterator></string></iostream></algorithm>…

C++1z 文字列検索アルゴリズム

C++

C++1zでは、文字列内の文字列を高速に検索するためのアルゴリズムとして、「ボイヤー・ムーア法 (Boyer-Moore)」と「ボイヤー・ムーア・ホースプール法 (Boyer-Moore-Horspool)」が導入されます。 これは、既存のstd::search()アルゴリズムを拡張する形で行…

C++1z 多相アロケータとメモリプール

C++

C++1zから、アロケートする型を規定しないアロケータと、それを利用したメモリプールの仕組みが導入されます。 std::allocator<T>クラスは型Tのオブジェクトをアロケートする機能を提供しますが、アロケートする型ごとにアロケータオブジェクトが必要になり、メ</t>…

C++1z 文字配列をコピーせず参照してbasic_stringライクな操作をするstring_view

C++

C++1zでは、所有権を持たない文字列クラスとして、basic_string_viewクラスが導入されます。その別名として、char文字配列を扱うstring_view、char32_t文字配列を扱うu32string_viewなどが定義されます。 このクラスは、文字列リテラルような文字配列に対し…

C++1z 型安全な共用体variantクラス

C++

C++1zから、型安全な共用体(type-safe union)の実装であるvariantクラスが導入されます。 このクラスは、テンプレート引数で与えた候補型のリストに含まれる型のオブジェクトを代入できる型です。また、ビジター関数オブジェクトを使用することにより、現在…

C++1z 統一的な有効値と無効値の表現をもつoptionalクラス

C++

C++14で入りそうで入らなかったoptionalクラスですが、C++1zで入ることになりました。 optionalは、テンプレート引数で指定した型の値を有効値、std::nulloptという特殊なオブジェクトを無効値と見なす型です。 ひとつの型で有効値と無効値を表すために、int…

C++1z なんでも代入できるanyクラス

C++

C++1zでは、コピー可能かムーブ可能であればどんな型でも代入できるanyクラスが入ります。C++には全ての型の継承元のobjectクラスというものはないので、その代わりにこのクラスを使えます。 このクラスのために、<any>ヘッダが新規追加されます。 #include <iostream> #inc</iostream></any>…

C++1z shared_ptr::weak_type

C++

C++1zから、shared_ptrの入れ子型としてweak_typeが追加されます。 これは、shared_ptr<T>に対するweak_ptr<T>型の別名です。 shared_ptrの要素型を取り出してweak_ptrのテンプレート引数を埋めることが冗長なコードになっていたための対処です。 shared_ptr<T> sptr </t></t></t>…

次回のBoost.勉強会は札幌です

C++

Boost.勉強会 #20 東京に参加された皆さま、おつかれさまでした。発表資料はboostjpの以下のページにまとめてあります。 Boost.勉強会 #20 東京 - boostjp 次回のBoost.勉強会は、札幌で行います。主催は@ignis_fatuusさんです。 Boost.勉強会 #21 札幌 - co…

明日はBoost.勉強会 東京です

C++

Boost.勉強会 #20 東京 - connpass 明日はBoost.勉強会です。いつものように、IIJ様の会場をお借りして開催します。 私はBoost 1.61.0のアップデート内容と、C++1z (C++17になる予定のバージョン)の全容を解説します。 発表資料は、boostjpサイトの以下のペ…

C++1z not_fn

C++

これまで、述語(predicate)を反転させるためには、std::not1()とstd::not2()という関数がありました。 これらの関数はそれぞれ1引数の述語関数オブジェクト、2引数の述語関数オブジェクトを対象としますが、C++11で導入された可変引数テンプレートがあれば、…

C++1z basic_string::data()メンバ関数の非const版

C++

basic_stringクラスが保持している動的文字配列の生ポインタを取得するdata()メンバ関数ですが、C++14まではconstメンバ関数のみ用意されていました。 C++1zでは、非const版のdata()メンバ関数が追加されます。これにより、char*を要求するインタフェースに…

C++1z emplace_frontとemplace_backで追加された要素を返す

C++

シーケンスコンテナのemplace_front()メンバ関数とemplace_back()メンバ関数は、C++14では戻り値型がvoidでしたが、C++1zでは追加された要素への参照が返るようになります。 これは、追加した要素をすぐ使いたい場合に、以下のような冗長なコードになってい…

C++1z owner_lessで任意の要素型を持つshared_ptr同士を比較できるようにする

C++

所有権ベースの小なり比較を行うstd::owner_less関数オブジェクトですが、そのクラステンプレートのパラメータによってスマートポインタの要素型を制約してしまうため、以下のような比較ができませんでした。 shared_ptr<int> sp1; shared_ptr<void> sp2; shared_ptr<long> sp</long></void></int>…

C++1z 時間の丸め演算

C++

時間ユーティリティライブラリの<chrono>には、精度が下がる単位変換をする場合に使用するduration_cast()関数があります。 C++1zでは、このときの丸め演算をユーザーが選択するための機能が導入されます。 まず、整数を時間間隔の値型とするdurationのための、floor</chrono>…

C++1z hypot関数の3引数版

C++

C++11で<cmath>に追加されたhypot()関数ですが、2引数(2次元)の演算のみが用意されていました。 C++1zでは、3引数版が追加されます。動機としては、科学計算や工学アプリケーションで3次元の演算をすることが多いためだそうです。 // <cmath> namespace std { double hypot</cmath></cmath>…

C++1z 数学の特殊関数

C++

C++1zでは、C++11のころから繰り越されていた数学の特殊関数(special functions)が導入されます。 一覧としては、以下になります: 関数名 説明 assoc_laguerre ラゲールの陪多項式 associated Laguerre polynomials assoc_legendre ルジャンドルの陪多項式 …

C++1z false sharingとtrue sharingの制御

C++

C++1zから、並行プログラミングで問題になりうる、キャッシュの無効化問題を制御できるようになります。 false sharingの制御 struct keep_apart { atomic<int> cat; atomic<int> dog; }; このような構造体がある場合、catとdogが同じキャッシュラインに乗ることがあり</int></int>…

C++1z 値を範囲内に収めるclamp()関数

C++

値を、min <= v <= maxのように範囲内に収める関数として、clamp()が定義されます。 std::min(std::max(min_value, x), max_value)のようにするのと同等の効果があります。 引数の順番は、対象の値、最小値、最大値です。戻り値として範囲内に丸められた値が…

C++1z swap可能かを判定する型特性クラス

C++

swap操作をラップした関数のnoexcept条件を書きやすくすることを主な目的として、C++1zから以下の型特性クラスが追加されます。 型Tがswap可能かを判定するis_swappable<T> 型Tと型Uの組み合わせでswap可能かを判定するis_swappable_with<T, U> 例外を送出せずにswap</t,></t>…

C++1z 現在発生している例外の数を取得するuncaught_exceptions()関数

C++

C++98時点で、捕捉していない例外があるかどうかを判定するstd::uncaught_exception()関数が定義されていました。この関数は、例外が送出されてから捕捉されるまでの間でtrueを返します。 C++1zでは、捕捉していない例外がいくつあるかを返すstd::uncaught_e…

Boost.勉強会 #20 東京をやります

C++

Boost.勉強会 #20 東京 - connpass 2016年07月23日に、IIJさんの会場をお借りして、Boost.勉強会を開催します。 今回私は、C++1zについて話す予定です。 皆さまのご参加をお待ちしております。

C++1z atomic<T>::is_always_lock_free

C++

C++11時点では、atomic<T>クラステンプレートの非静的メンバ関数としてis_lock_free()が用意されていました。この関数は、T型のatomicオブジェクトがロックフリーに振る舞うかどうかをbool値で返します。この関数が返す値はTの型ごとに静的な値ですが、atomicク</t>…

C++1z コンテナに不完全型の最小サポートを追加

C++

定義が完了していない不完全型(incomplete type)はsizeofがとれないので、アロケータとそれを使用するコンテナの実装が少し難しくなる場合があります。ですが、自分自身の型のオブジェクトがいくつあるかカウントする、というような場合に以下のようなコード…

C++1z ファイルシステムライブラリ

C++

C++1zでは、ファイルパス、ディレクトリ、ファイルのコピー・移動などを扱うファイルシステムライブラリが導入されます。 このライブラリは、Boost Filesystem Library v3をベースにしています。basic_path<CharT>のように文字型をパラメータとするのではなく、path</chart>…

C++1z オブジェクトをconstにするas_const関数

C++

C++1zから<utility>ヘッダに、as_const()関数テンプレートが追加されます。 この関数は、引数として渡されたオブジェクトをconstにします。その際、オブジェクトのコピーは発生しません。また、この関数に右辺値は渡せません。 #include <iostream> #include <utility> int main() { std:</utility></iostream></utility>…

C++1z shared_from_thisの指す先が書き換わらないことを規定

C++

thisポインタをstd::shared_ptrとして取得するための機能として、std::enable_shared_from_this基本クラスとそのメンバ関数shared_from_this()があります。 std::enable_shared_from_thisから派生したクラスのオブジェクトをnewしてshared_ptrのコンストラク…

C++1z reference_wrapperがTriviallyCopyableであることを保証

C++

C++11では、関数テンプレートに渡す引数を参照として渡すことを明示するstd::reference_wrapperクラスが導入されました。 これは通常、オブジェクトへの参照を受け取ってそのポインタを保持しておく、という簡単な方法で実装されます。このような実装になっ…

C++1z コンテナの要素情報にアクセスする非メンバ関数

C++

C++11では、範囲for文を拡張することを目的として、std::begin()、std::end()という非メンバ関数が導入されました。 std::vector<T> v; // 先頭要素を指すイテレータ、終端イテレータを非メンバ関数で取り出す decltype(v)::iterator first = std::begin(v); de</t>…

C++1z 値を返す型特性クラスのconstexpr変数テンプレート版

C++

C++14では、f<Arg>::typeのような型を返す型特性クラスに対して、f_t<Arg>のように_tをクラス名に付けて::typeを省略するエイリアステンプレート版が追加されました。 C++1zでは、f<Arg>::valueのような値を返す型特性クラスに対して、f_v<Arg>のように_vをクラス名に付けて::val</arg></arg></arg></arg>…

C++1z shared_mutex

C++

C++14では、Readers-writerパターンという、読み込み操作が多い状況で使うミューテックスとして、std::shared_timed_mutexクラスが導入されました。 C++1zでは、タイムアウト付きロック取得機能がないクラスとして、shared_mutexクラスが導入されます。 // <shared_mutex> </shared_mutex>…

C++1z スコープ付きロックの可変引数版

C++

関数内でロックを取得したミューテックスを、関数の終わりで確実にロックを手放すstd::lock_guard<MutexType>クラスがありますが、C++1zから可変個のミューテックス型およびミューテックスオブジェクトをとるstd::scoped_lockクラスが追加されます。 std::mutex m1; std</mutextype>…

C++1z コンパイル時条件の論理演算

C++

C++11時点で、コンパイル時条件をハンドリングするメタ関数として、以下があります: std::conditional (boost::mpl::if_c相当) std::enable_if (boost::mpl::enable_if_c相当) std::is_same C++1zからは、コンパイル時条件の論理演算を行う3つのメタ関数と…

C++1z bool_constant

C++

C++1zから、標準ライブラリの<type_traits>に、integral_constantの第1テンプレート引数をboolにした別名のbool_constantが追加されます。 それにともない、true_typeとfalse_typeの定義が、integral_constantを使ったものからbool_constantを使ったものに変更されます。 </type_traits>…

Boost 1.61.0がリリースされました

C++

Version 1.61.0 - Boost C++ Libraries Boost 1.61.0リリースノート - boostjp Boost 1.61.0がリリースされました。 リリースノートはいつものように、boostjpサイトで翻訳 + 情報補完したものを公開しています。今回は新ライブラリが4つもあります。 GPGPU…

C++1z 関数が呼び出し可能かを判定する型特性

C++

C++1zからは、関数が呼び出せるかどうかをコンパイル時に判定する型特性として、is_callableとis_nothrow_callableの2つが<type_traits>に追加されます。 // <type_traits> namespace std { template <class Fn, class... ArgTypes> struct is_invocable; template <class R, class Fn, class... ArgTypes> struct is_invocable_r; template <class Fn, class... ArgTypes> …</class></class></class></type_traits></type_traits>

C++1z constexprラムダ

C++

C++1zからは、ラムダ式をconstexprとして定義・実行できるようになります。 ラムダ式をconstexprにするには、これまでmutableを付けていたところに、constexprを付けます。 int main() { auto add = [](int x) constexpr { return x + 1; }; static_assert(a…

C++1z 範囲for文のためのbegin()とend()関数が、異なる型を返すことを許可

C++

C++11時点での範囲for文は、begin()関数とend()関数が同じ型のイテレータオブジェクトを返すことを要求していました。 しかし、end()の方のイテレータは特殊な型にしたいことがたまにあります。ストリームイテレータを作ろうとするときとかもそうだと思いま…