C++

標準C++の欠陥解決は、過去のバージョンに遡って適用される

C++

C++17で入る予定の、可変引数でミューテックスを受け取ってスコープを抜けたらロック解除するscoped_lockクラスですが、C++17がDIS (Draft International Standard) の段階になり、仕様の手直しがもうほぼできない段階になってから、引数順の変更が行われま…

インクルードするディレクトリをマクロ定数として持つ

C++

とある事情から「インクルードするディレクトリが長いので何度も書きたくない」という状況になり、インクルードするディレクトリをマクロ定数に持って、インクルードするファイル名と連結してインクルードしたい、ということがありました。 そんなときの対応…

C++17標準ライブラリの細かい変更いろいろ その1

C++

最近cpprefjpに書いたものを列挙します。 assertマクロがconstexpr関数内で使用できるようになった std::next()関数のイテレータ要件がForward IteratorからInput Iteratorに緩和された std::addressof()がconst T&&の引数を禁止にした。addressof<const T>(T())のよ</const>…

標準ライブラリの実装で追加のnoexceptが付いている場合がある

C++

標準ライブラリの仕様でnoexceptが付いているものは、実装にもnoexceptを付けることが求められます。 しかし、標準ライブラリの仕様でnoexceptが付いていない場合、実装にnoexceptを付けないことは求められません。 たとえば、libc++のstd::vectorクラスでは…

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

C++

Version 1.64.0 - Boost C++ Libraries Boost 1.64.0リリースノート - boostjp Boost 1.64.0がリリースされました。リリースノートを日本語翻訳したものは、いつものようにboostjpサイトで公開しています。 新ライブラリ Process マルチプラットフォームで動…

C++1zの言語拡張まとめ

2017年中に改訂される予定のC++14の次のバージョン、仮称C++1zの更新内容をまとめました。正式名称はISO/IEC 14882:2017、通称C++17になる予定です。 C++1zの概要 C++17は、C++11ほど大きな変更はありませんが、重要な言語機能(構造化束縛とか)や、広く適用…

C++1z using宣言のパック展開

C++

using宣言 (using-declaration) には、2つの用途があります: メンバ関数を、基本クラスと派生クラスでオーバーロードする 識別子の名前空間を省略できるようにする これらusing宣言に指定する識別子が、ひとつだけでなく、カンマ区切りで複数指定できるよう…

C++1z shared_ptr::use_count()の仕様を明確化し、unique()を非推奨化

C++

std::shared_ptrクラスのメンバ関数use_count()とunique()は参照カウンタがいくつあるか (リソースを共有しているユーザーが何人いるか) を返すもので、デバッグ目的にしか使用しません。また、複数スレッドから使用するには、仕様が不明確でした。 use_coun…

C++1z shared_ptrの配列対応

C++

C++1zでは、unique_ptr<T[ ]>と同様に、shared_ptrもテンプレート引数をshared_ptr<T[ ]>もしくはshared_ptr<T[N]>のように指定することで、配列を扱えるようになります。 std::shared_ptr<double[1024]> p1 {new double[1024]}; std::shared_ptr<double[]> p2 {new double[n]}; // 添字アクセス double</double[]></double[1024]></t[n]></t[></t[>…

C++1z Chronoライブラリ durationクラスとtime_pointクラスの変更操作をconstexpr対応

C++

ChronoライブラリはC++11, C++14と段階的にconstexprの対応を進めてきました。C++1zでは、durationの変更操作、time_pointの変更操作が全てconstexpr対応します。 template <class Rep, class Period = ratio<1>> class duration { public: constexpr duration& operator++(); constexpr duratio</class>…

C++1z char_traitsのconstexpr対応

C++

C++1zでのstring_viewの追加にともない、その実装に必要なstd::char_traitsクラスの一部メンバ関数がconstexprに対応します。 constexpr対応するのは、以下のメンバ関数です: static constexpr int compare(const char_type* s1, const char_type* s2, size…

C++1z 値のコピー省略を保証

C++

関数の戻り値のコピーを発生させない手法として、RVO (Return Value Optimization) やNRVO (Named Return Value Optimization) といった最適化がありました。 // RVOの最適化が動作した場合 struct Foo {}; Foo foo() { return Foo(); } Foo x = foo(); // F…

整数を、任意の基数の文字列に変換する

C++

除算と剰余で作れる。テーブルを拡張すれば何進数でもいける。 #include <iostream> #include <cassert> #include <string> #include <sstream> template <class Integer> std::string to_base_string(Integer x, int base) { assert(base >= 2 && base <= 16); if (x == 0) return "0"; const std::string table</class></sstream></string></cassert></iostream>…

浮動小数点数を2の乗数で割る

C++

a/bをする場合、bが2の乗数であれば「aの指数 - log2(b)」で除算ができます。 #include <iostream> #include <bitset> #include <cstdint> #include <cassert> #include <cmath> union SingleFloat { float value; struct { int fraction : 23; int exponent : 8; bool sign : 1; } parts; }; SingleFloa</cmath></cassert></cstdint></bitset></iostream>…

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

C++

Version 1.63.0 - Boost C++ Libraries Boost 1.63.0リリースノート - boostjp Boost 1.63.0がリリースされました。リリースノートはいつものように、翻訳・情報補完したものをboostjpサイトで公開しています。 このバージョンは、まだリリースされていないV…

Nが2の何乗かを調べる

C++

C++11から標準数学ライブラリに入ったstd::log2()関数を使えば、Nが2の何乗かを取得できます。 #include <iostream> #include <cmath> int main() { std::cout << std::log2(4.0) << std::endl; std::cout << std::log2(8.0) << std::endl; // 8は2の3乗 std::cout << std::lo</cmath></iostream>…

C++11 標準ストリームへの出力はスレッドセーフ

C++

本記事の本題とする、「一回の書き込みにすれば排他制御は必要ない」という部分が誤りであったため、本記事を取り下げます。 C++11から標準ライブラリに、並行プログラミングのための各種機能が入った影響は、入出力のライブラリにもあります。スレッドの存…

C++1z if constexpr文

C++

C++1zから、コンパイル時条件によって分岐するif constexpr文が導入されます。これにより、再帰やヘルパ関数を書かなくて済むケースが多くなります。 D言語にあるstatic if文のようなものです。 template <class T, class... Rest> void g(T&& p, Rest&&... rs) { if constexpr (size</class>…

C++1z 非推奨だった古い例外仕様を削除

C++

C++11でnoexceptが導入されたことによって非推奨になっていたthrowキーワードによる関数の例外仕様が、C++1zで削除されます。 throwキーワードによる例外仕様とは、void f() throw(std::runtime_error)のように、その関数がどの種類の例外を送出する可能性が…

C++1z 例外仕様を型システムの一部にする

C++

C++1zからは、noexceptによる関数の例外仕様が、型の一部として扱われるようになります。 互換性のためにnoexceptな関数ポインタから非noexceptな関数ポインタには変換できます。しかし、非noexceptな関数ポインタからnoexceptな関数ポインタには、変換でき…

C++11 最近接偶数への丸め

C++

C++11では<cmath>にいろいろ関数が追加されていますが、丸め演算も増えています。 C++11で最近接偶数への丸めを使いたい場合は、std::nearbyint() (near by int)という関数がありますので、それを使いましょう。 #include <iostream> #include <cmath> int main() { std::cout << std</cmath></iostream></cmath>…

C++1z 畳み込み式

C++

C++1zでは、「畳み込み式 (Fold expressions)」という機能が入ります。これは可変引数テンプレートのパラメータパックに対して集計操作を行うためのものです。 たとえば、整数のシーケンスを与えてその合計値を求める計算は、以下のように書けます: #includ…

C++1z トライグラフを削除

C++

C言語から引き継がれた「トライグラフ (trigraph)」という機能は、ASCIIより小さなISO/IEC 646という文字コードでもプログラムが書けるように用意された機能で、いくつかの文字の代替表現を使用できるようにするものです。 トライグラフ表現 置き換え後の文…

C++1z 構造化束縛

C++

C++1zから、タプルやクラスを分解する「構造化束縛 (Structured Binding)」という機能が入ります。他の言語では多重代入のように呼ばれているもので、C++11標準ライブラリのstd::tie()関数の代わりとして使用できます。 以下は、タプルを返す関数の戻り値を…

C++1z 単一要素の波カッコ初期化をTに推論する

C++

単一要素の波カッコ初期化(braced init list)を、(代入構文ではなく)直接autoで受けた場合のルールが、以下のように変更になります: auto a {1}; // C++14まではinitializer_list<int> // C++1zではint auto b {1, 2}; // C++14まではinitializer_list<int> // C++1z</int></int>…

C++1z if文とswitch文の条件式と初期化を分離

C++

for文が for (初期化式; 条件式; 加算式)になっているのと同様に、if文とswitch文にも、条件式の前準備としての初期化式をif (初期化式; 条件式)のように書けるようになります。 // mapへの要素挿入 if (auto p = m.try_emplace(key, value); !p.second) { /…

C++1z インライン変数

C++

C++14まで、関数に対してインライン化の指定ができましたが、C++1zでは変数にもインライン指定ができるようになります。 変数に対してインライン指定をすると、翻訳単位を跨いでひとつのオブジェクトになります。これによって、ヘッダファイルで変数を定義で…

C++1z 非推奨だったbool型に対するインクリメント演算子を削除

C++

bool型に対してインクリメントすると固定でtrueになる仕様がありましたが、この仕様はC++98時点で非推奨になっていました。C++1zではこの機能が削除されます。 以下のようなコードは、C++1zではコンパイルが通らなくなりますので注意してください。 #include <cassert></cassert>…

C++1z 非推奨だったregisterキーワードを削除

C++

C++11から非推奨となっていたregisterキーワードが、C++1zで削除されます。 ただし、C++11のautoのように、registerキーワードを将来の標準でほかの用途に再利用することを考慮して、予約語としては残ります。 C++1zでは、register記憶クラス指定子を使用し…

C++1z 全ての非型テンプレート引数の定数式評価を許可

C++

C++1zでは、非型テンプレート引数(non-type template argument)で扱える型はとくに変わりませんが、渡せる値についての制限緩和が行われます。 今回緩和されるのは、ポインタの値です。C++14までは、以下のような制限がありました: 静的記憶域を持つ完全オ…

C++1z 非型テンプレートパラメータのauto宣言

C++

C++14まで、以下のように書いていた「指定された型の定数を受け取る」意図の非型テンプレートパラメータ(non-type template parameter)ですが、 template <class T, T V> struct X; X<int, 3>; C++1zではこの用途のためのシンタックスシュガー(糖衣構文、syntactic sugar)が導入さ</int,></class>…

C++1z クラステンプレートのテンプレート引数推論

C++

C++1zでは、クラステンプレートのテンプレート引数が推論されるようになります。 例として、冗長なコードになりがちなstd::lock_guardクラスを使用した以下のコードは、 std::mutex m1; void f() { std::lock_guard<std::mutex> lk(m); } C++1zでは以下のようにstd::lock</std::mutex>…

C++1z 入れ子名前空間の定義

C++

C++1zでは、ネストした(入れ子になった)名前空間の定義が簡潔に書ける構文が追加されます。 // C++14 namespace A { namespace B { namespace C { }}} // C++1z namespace A::B::C { } 入れ子名前空間の定義では、inlineや属性の指定はできません。 参照 N42…

C++1z 不明な属性を無視する

C++

標準で定義される属性のほかに、実装定義の属性がありますが、その実装定義の属性を認識できない他の処理系では、その実装定義の属性は無視されることが規定されます。属性指定の文脈で#ifdefを書かなくてよくなります。 // GCC/Clangではgnu::deprecated属…

C++1z 属性の名前空間指定に繰り返しをなくす

C++

標準外の属性は、名前空間内に定義されている場合があります (例として、GCCが定義している属性はgnu名前空間に属している)。属性指定の文脈でその名前空間を何度も書かなくてよいように、名前空間を省略するための機能がC++1zで入ります。 [[ using CC: opt…

C++1z 名前空間と列挙子への属性付加を許可

C++

C++1zでは、名前空間と列挙子の構文に、属性が付けられるようになります。標準の属性としては、[[maybe_unused]]属性が列挙子に付けられるようになります。 namespace 名前空間名 属性 {} enum 列挙型 { 列挙子 属性, }; // [[maybe_unused]]属性の例 enum …

C++1z 戻り値を捨ててはならないことを指定する[[nodiscard]]属性

C++

C++1zから、関数の戻り値をユーザーに無視しないでほしい場合に指定する[[nodiscard]]属性が導入されます。 この属性は、エラーが起きた状態でエラーを無視して正常として処理を続けないでほしいような状況で使用します。 struct error_info { … }; // 関数f…

C++1z 使用しない可能性のある変数に対する警告を抑制するための[[maybe_unused]]属性

C++

関数void f(int a) {}のパラメータaのように、実行時に使用しない可能性のある識別子は、コンパイル時に警告が出力されることがあります。 使用しないことが意図したものであることをコンパイラに伝えて警告を抑制するために、C++1zから[[maybe_unused]]属性…

C++1z フォールスルー時の警告を抑制する[[fallthrough]]属性

C++

switch文で下のcaseに処理を流すことを「フォールスルー (fallthrough)」と言います。 #include <iostream> int main() { int n = 1; switch (n) { case 1: std::cout << "1" << std::endl; // break; を書かずに、処理を下に流す case 2: std::cout << "2" << std::en</iostream>…

C++1z C標準ライブラリの参照をC11に更新

C++

C++14段階では、C++標準ライブラリはC99のC標準ライブラリを参照していました。C++1zでは、C11標準ライブラリを参照するようになります。C11標準ライブラリのすべての機能に対応するわけではありません。 <stdatomic.h>, <stdnoreturn.h>, <threads.h>に対応するC++ヘッダは用意しない <cfloat>に以下のマク</cfloat></threads.h></stdnoreturn.h></stdatomic.h>…

C++1z 非推奨だったiostreamのエイリアスを削除

C++

標準入出力ライブラリで、C++98のころから非推奨だった型の別名と関数の別名が、C++1zで削除されます。 まず、std::ios_baseクラスの以下のメンバ型が削除されます: namespace std { class ios_base { public: typedef T1 io_state; typedef T2 open_mode; …

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

C++

Version 1.62.0 - Boost C++ Libraries Boost 1.62.0リリースノート - boostjp Boost 1.62.0がリリースされました。 リリースノートはいつものように、boostjpサイトで翻訳したものを公開しています。Flastさん、協力ありがとうございました。 新ライブラリ …

C++1z std + 数字の名前空間を予約

C++

C++の今後のメジャーバージョンアップで標準ライブラリに大きな変更を加えるときのために、「std + 数字」の名前空間が予約されます。std2とかの名前空間を作りたいのだそうです。 参照 P0180R2 Reserve a New Library Namespace Future Standardization Alt…

C++1z 並列アルゴリズムライブラリ

C++

C++1zでは、並列アルゴリズムのライブラリが導入されることになりました。このライブラリは、<algorithm>, <numeric>, <memory>で定義されるアルゴリズムのオーバーロードという形で提供されます。 using namespace std::execution; // 実行ポリシーの名前空間 std::vector<int> v = … std::so</int></memory></numeric></algorithm>…

C++1z 初期化子リストからpairとtupleを構築しやすくするための改善

C++

C++14では、以下のコードがコンパイルエラーになります。 std::tuple<int, int> pixel_coordinates() { return {10, -15}; // コンパイルエラー } struct NonCopyable { NonCopyable(int); NonCopyable(const NonCopyable&) = delete; }; std::pair<NonCopyable, double> pmd{42, 3.14}; // </noncopyable,></int,>…

C++1z has_unique_object_representations型特性

C++

少しまえから、オブジェクトからハッシュ値の計算を自動的に行いたい、という話がでていました。C++1z時点ではそのサポートは入りませんが、前準備として、自動的にハッシュ値を求められる型かを判別するためのhas_unique_object_representationsという型特…

C++1z 未初期化メモリのアルゴリズムと、デストラクタ呼び出しの関数

C++

C++標準ライブラリには、データ構造を実装する際に使用する未初期化メモリに対するアルゴリズムが<memory>ヘッダで定義されています。 C++1zでは、厳しいパフォーマンス要求があるデータ構造を実装しやすくするためのアルゴリズムが、いくつか定義されます。これらは</memory>…

C++1z unique_ptrのテンプレート代入演算子に、不足していたSFINAEルールを追加

C++

unique_ptrの以下の代入演算子に、オーバーロード解決に参加する条件が不足していました。 template <class U, class E> unique_ptr& operator=(unique_ptr<U, E>&& u) noexcept; C++14時点では、以下の2つの条件になっています。 unique_ptr<U, E>::pointerが、pointerに暗黙変換可能な型</u,></u,></class>…

C++1z 乱数用語を変更

C++

C++11で導入された乱数ライブラリでは、乱数生成器のコンセプトに 「URNG (Uniform Random Number Generator, 一様乱数生成器)」という用語を使用していました。 しかし、一般的なURNGの用語とは異なり、C++の乱数生成器は一度の呼び出しで、(32ビットを超え…

C++1z memory_order_consumeを一時的に非推奨化

C++

並行プログラミングでのアトミック操作をする上で、処理の順序保証をする仕組みとしてメモリオーダーがあります。C++の標準ライブラリではメモリオーダーが何種類か提供されていますが、C++1zではmemory_order_consumeというメモリオーダーが一時的に非推奨…