本の虫

著者:江添亮
ブログ: http://cpplover.blogspot.jp/
メール: boostcpp@gmail.com
Twitter: https://twitter.com/EzoeRyou
GitHub: https://github.com/EzoeRyou

アマゾンの江添のほしい物リストを著者に送るとブログ記事のネタになる

筆者にブログのネタになる品物を直接送りたい場合、住所をメールで質問してください。

C++標準化委員会の文書: P0033R1-P0059R1

P0033R1: Re-enabling shared_from_this

enable_shared_from_thisの規程を書き直す提案。

enable_shared_from_thisとは、クラスの基本クラスとして使うと、shared_from_thisというメンバー関数が追加され、そのクラスのオブジェクトを現在所有しているshared_ptrが返る。

class X : public std::enable_shared_from_this<X> { } ;

int main()
{
    auto sp1 = std::make_shared<X>() ;

    // sp1とsp2は所有権を共有する
    auto sp2 = sp1->shared_from_this() ;
}

問題は、複数のshared_ptrに所有された場合どうなるのだろうか。

X * ptr = new X{} ;
std::shared_ptr<X> sp1( ptr ) ;
std::sahred_ptr<X> sp2( ptr, [](void *){} ) ;

// sp1とsp2のどちらと所有権を同じくするshared_ptrが変えるのか?
ptr->shared_from_this() ; 

規格はこの場合の挙動について述べていない。既存の実装はすべて、sp2はsp1を上書きする。しかしこの挙動は、単にこの可能性を考えなかっただけにすぎない。Boostのshared_ptrは書きかえない。これはユーザーのフィードバックによるものである。

これを考察すると、最初のshared_ptrが所有権を持つのが自然で、デリーターが何もしないshared_ptrを作りたいことはあるかもしれず、この例が動いてほしい場合はあるが、動かないでいて欲しい場合はない。そこで、最初のshared_ptrから上書きされない決定がなされた。

また、weak_ptrを返すweak_from_thisも追加された。

P0035R1: Dynamic memory allocation for over-aligned data

operator newにオーバーアラインを守るオーバーロードを追加する提案。

問題は、この提案だとだいぶ文法が汚いことになるのではないか。

auto * ptr = new(static_cast<std::align_val_t>(32)) int[128] ;

P0037R1: Fixed-Point Real Numbers

固定少数点数ライブラリ、fixed_point<ReprType, Exponent>の提案。

P0040R1: Extending memory management tools

メモリ管理のためのライブラリとして、デストラクターを呼ぶdestroy, uninitialized_move, uninitialized_value_construct, uninitialized_default_constructを追加。これらはコア言語機能だけでも行えるが、記述が面倒なのでライブラリとしてあると便利だ。

P0046R1: Change is_transparent to metafunction (Revision 1)

連想コンテナーでheterogeneous lookupを許可するかどうかを判断するにはcomparatorにis_transparentというネストされた型名が必要だが、これをpermits_heterogeneous_lookup<T>というわかりやすいメタ関数に置き換える提案。

[PDF] P0052R1: Generic Scope Guard and RAII Wrapper for the Standard Library

汎用RAIIラッパーライブラリの提案。

#include <scope>

int main()
{
    {
        auto file = std::make_unique_resource( fopen("hoge", "w"), &fclose ) ;
    }

    {
        auto memory = std::make_unique_resource( malloc( 100 ), &free ) ;
    }

    {
        auto s1 = std::make_scope_exit( []{ std::cout << "leave scope" ; } ) ;
        auto s2 = std::make_scope_success( []{ std::cout << "leave scope normaly" ; } ) ;
        auto s3 = std::make_scope_fail( []{ std::cout << "leave scope by exception"} ) ;
    }

}

unique_resourceは、ある型のオブジェクトを保持し、破棄されるタイミングでそのオブジェクトを引数に渡してデリーターを呼んでくれる。

scoped_exitは、脱出関数を引数に取り、破棄されるタイミングで脱出関数を呼んでくれる。make_scope_xxxには3種類ある。exitはスコープから抜けたら必ず脱出関数を呼ぶ。successは例外によらずにスコープを抜けた場合にのみ脱出関数が呼ばれる。failは、例外でスコープを抜けた場合のみに脱出関数が呼ばれる。

もうひとつ、make_unique_resource_checked(R r, S invalid, D d)という関数があり、これはrがinvalidに等しい場合、返されるunique_resourceは、すでにreleaseが呼び出されたあとである。

今回の変更点は、unique_resourceのリソースとデリーターは、無例外コピー可能な型でなければならないとするもの。これにより設計が単純になり、無例外コピー可能ではないstd::functionも使う必要がなくなる。また、リファレンスを渡す場合は、std::ref/crefをユーザーが使わなければならない。

P0055R1: On Interactions Between Coroutines and Networking Library

提案されているネットワークライブラリの非同期呼び出しとしてfutureが使われているが、コルーチンを使うようにしたらオーバーヘッドが下がった上にコードも簡潔になったという文書。

[PDF] P0057R2: Wording for Coroutines

コルーチンの文面案。

[PDF] P0058R1: An Interface for Abstracting Execution

スレッドプール、協調型ファイバー、SIMD、GPGPUまで含めた実行媒体を表現できるexecutorライブラリの提案。スレッドからSIMDやGPGPUまでを包括したいいライブラリが設計できるとは思えない。

[PDF] P0059R1: A proposal to add a ring span to the standard library

ring_spanライブラリの提案。

この提案は名前が悪い。ring_viewとでも改名すべきではないだろうか。

いわゆるリングバッファーライブラリなのだが、前回の提案が固定長リングバッファーと動的リングバッファーの2つがあったのに対し、この提案では、ring_spanに統一されてしまっている。ring_spanは連続したストレージ上にリングバッファーを構築するが、ストレージの所有はしない。ストレージはユーザーが用意する。

つまりデフォルト構築もできないコンテナーなのだが、すごく使いづらい気がする。

ドワンゴ広告

来月ドワンゴで開催する予定の勉強会にレーザープリンターを持ち込みたいという猛者がいるので困惑しているが、PostScriptのデモのための実行環境としては極めて普通であり当然予期すべき事態ではある。

ドワンゴは本物のC++プログラマーを募集しています。

採用情報|株式会社ドワンゴ

CC BY-ND 4.0: Creative Commons — Attribution-NoDerivatives 4.0 International — CC BY-ND 4.0