listの要素位置を移動する

splice()メンバ関数を使用して、std::listの要素位置を移動できるようです。

#include <iostream>
#include <list>
#include <iterator>

int main()
{
    std::list<int> ls = {1, 2, 3, 4, 5};

    // 0番目の要素を、2番目に移動
    ls.splice(std::next(ls.begin(), 2 + 1), ls, ls.begin());

    for (int x : ls) {
        std::cout << x << std::endl;
    }
}

出力:

2
3
1
4
5

移動元のイテレータは、無効になりません。

#include <iostream>
#include <list>
#include <iterator>

int main()
{
    std::list<int> ls = {1, 2, 3, 4, 5};

    // 0番目の要素を、2番目に移動
    decltype(ls)::iterator from = ls.begin();
    decltype(ls)::iterator to = std::next(ls.begin(), 2 + 1);
    ls.splice(to, ls, from);

    std::cout << *from << std::endl;
}

出力:

1

いちおう、std::forward_listの例:

#include <iostream>
#include <forward_list>
#include <iterator>

int main()
{
    std::forward_list<int> ls = {1, 2, 3, 4, 5};

    // 0番目の要素を、2番目に移動
    ls.splice_after(std::next(ls.before_begin(), 2 + 1),
                    ls,
                    ls.before_begin());

    for (int x : ls) {
        std::cout << x << std::endl;
    }
}

出力:

2
3
1
4
5

参照

NaNとinfinityの文字列化

C++11で<string>ヘッダに追加されたstd::to_string()関数ですが、この関数にfloat型の値NaNもしくはinfinityを渡したら、どんな結果になるのか。エラーになるのか、もしくは正常に終了するならどんな文字列になるか。やってみましょう。

#include <iostream>
#include <limits>
#include <string>

int main()
{
  using limits = std::numeric_limits<float>;

  std::cout << std::to_string(limits::quiet_NaN()) << std::endl;
  std::cout << std::to_string(limits::infinity()) << std::endl;
}

出力:

nan
inf

エラーにはならず、NaNは"nan"という文字列に、infinityは"inf"という文字列になりました。

この関数の挙動は、sprintf()関数に依存しています。floatdouble型なら、"%f"が使われます。そして、sprintf()の仕様もまた、fprintf()に依存していて、そこにNaNとinfinityの仕様について記載されています。

NaNは、"[-]nan"もしくは"[-]nan(n-char-sequence)"という形式(-は符号が付くかつかないか)、infinityは、"[-]inf"もしくは"[-]infinity"のどちらかが、実装定義によって決定し、返されます。

参照

C++14最後のドラフト仕様

N3936 Working Draft, Standard for Programming Language C++

C++14最後のワーキングドラフトが公開されました。このあと、ものすごく細かい修正は入るかもしれませんが、実質的にこれがC++14の言語仕様とほぼ同等になるでしょう。

このドラフトでの変更内容は、以下を参照:

N3938 Editor's Report

参照

レビュー『Boost C++ Application Development Cookbook』

新たなBoost本 『Boost C++ Application Development Cookbook』

id:wraith13 さんに送っていただいたので、読んでました。

この本の内容を一言で表すと、boostjpサイトでやっている「Boost逆引きリファレンス」です。

Boostは100以上のライブラリが含まれている巨大なプロジェクトなので、どこから始めればいいかわからない、という方向けに、「こういうことがやりたい!」から「どうやれば?」と調べる本になっています。

英語の本ですが非常に読みやすいので、初めて洋書を読む、という方はこの本から取り組んでみると入りやすいんじゃないかと思いました。

この本の各Tipsは、以下のような構成になっています。

  1. こんなことがやりたい
  2. 前準備として、このライブラリのリンクと、このライブラリの知識が必要だよ
  3. それをどうやって実現するか
  4. この機能は内部的にこんなことをしてるんだよ
  5. その他追加情報
  6. 詳細情報へのリンク

すごく親切な作りになってるので、手元に一冊置いておくと、便利に使えると思います。

対象となるBoostのバージョンは1.53.0です。Boostのコミッターが書いてるので、品質も安心です。

Boost.勉強会 #14 東京を開催しました。

Boost.勉強会 #14 東京 - boostjp

2014年3月1日(土)に、IIJさんの会場をお借りして、Boost.勉強会 #14 東京を開催しました。

資料は、上記boostjpページにまとめてあります。

私が話したことは、まずオープニング。

Boost.勉強会はわりとなーなーで運営してきたので、今回明確に「Boost.勉強会ルール」というのを導入しました。「発表会じゃなく勉強会なので、周りのことはあまり気にせず、質問はどんどんしていいんですよ」というだけですが、参加者の方々はいちおうご一読を。

私は今回、2つの発表をしました。

cpprefjpを支える技術

http://melpon.org/pub/cpprefjp

C++のリファレンスサイトcpprefjpでの、運営ツールについて話しました。

今回、私は初めて2人での発表をしてみたのですが、そこそこうまくいった気がします。

Boost.Graphの設計と、最短経路アルゴリズムの使い方いろいろ

タイトル通り、Boost.Graphの設計について話しました。

この資料を作りつつ今までの発表を振り返って、「自分はどんだけテンプレートが好きなんだ」と思ったりしました。

グラフは応用範囲が非常に広いデータ構造なので、気になった方はこの機会に遊んでみるといいと思います。

謝辞

Boost.勉強会の準備・進行はだいたいいつもなーなーでやってる関係で、勉強会当日に参加者の方々を急遽スタッフに抜擢してヘルプをお願いしてたりします。

入場のお手伝いをしていただいたyou_and_iさん、魔導書の販売をしていただいたかなはるさん、配信をしていただいたfadis_さん、ありがとうございました。

発表者と参加者の方々も、ありがとうございました。みなさんのおかげで、多くの有意義な議論ができたと思います!

次回はおそらく、5月の札幌になると思います。主催のhotwatermorningさんにバトンタッチ!

C++14 Fundamentals TS shared_ptrの配列サポート

N3920 Extending shared_ptr to Support Arrays, Revision 2

C++14後のLibrary Fundamentals TSでは、std::shared_ptrの配列サポートが予定されています。

std::unique_ptrのように、配列での部分特殊化を用意するのではなく、内部的にstd::is_array特性を使ってdeletedelete[ ]か、operator[ ]を定義するかどうかなどを分岐するようです。

std::shared_ptr<int[]> p(new int[3]);

p[0] = 3;
p[1] = 1;
p[2] = 4;

std::shared_ptrに指定できる型の形式は、従来のstd::shared_ptr<T>に加えて、std::shared_ptr<T[]>std::shared_ptr<T[N]>が許可される予定です。

Boostでは1.53.0から、配列をサポートしています。

なお、shared_ptrオブジェクトを作るヘルパ関数make_shared()の配列サポートも検討されていますが、

N3939 Extending make_shared to Support Arrays, Revision 2

これは現状、Technical Specificationには予定されていません。

参照

C++14 gets削除

C言語互換ライブラリの<cstdio>ヘッダで定義されていた、標準入力から1行を読む関数std::gets()が、C++14から削除されることになりました。

これは、C11でgets()関数が定義されなくなったので、それに合わせてC++14でも削除される、という参照仕様の単なるバージョン更新対応になります。

gets()関数は、バッファオーバーランのセキュリティ的な事情で、C99から非推奨になっていた関数です。C99以降はこの関数を使うと警告が出ていたはずなので、そこから15年経った今では、使っている人はほとんどいないはずです。

参照

C++14 シグナルハンドラでできることの制限緩和と明確化

N3910 What can signal handlers do?

これまでのシグナルハンドラに関する規定では、以下のような問題がありました。

  • 制限が強すぎるためにハンドラ内ではvolatile std::sig_atomic_tかロックフリーアトミックオブジェクトの変数しか扱えなかった。
  • 未定義動作となる仕様があったために、汎用的なシグナルハンドラを書くのが難しかった。

この提案では、ハンドラ内で使えるオブジェクトの制限が緩和され、volatileやロックフリーオブジェクトでなくてもシグナルハンドラ内で定義・使用できるようになります。ただし変数に対する操作は、ロックフリー操作のみが許可されます。

いまの提案仕様では、mutexは使えないそうです。ロックフリー操作で実装される、スピンロックのようなクラスは可能。

メモリオーダーの観点で仕様が見直されたので、未定義動作も少なくなります。

参照

C++14 Fundamentals TS 変数テンプレート版のType Traits

N3932 Variable Templates For Type Traits (Revision 1)

C++14で、型を返すType Traitsに対するエイリアステンプレート版が追加されることになりましたが、この提案は、値を返すType Traitsに変数テンプレート版を追加するというもの。

// これまで通りの、値を返すType Traits
constexpr bool b = is_const<T>::value;

// 変数テンプレート版
constexpr bool b = is_const_v<T>;

変数テンプレート版は、valueを意味する_vサフィックスが付きます。(初期提案は_cだった)

この提案は、std::optionalと同じくC++14後のLibrary Fundamental TSで導入される予定です。

参照