2015-06-23

C++標準化委員会の文書 2015-04 pre-Lenexaのレビュー: N4440-N4449

N4440: Feature-testing recommendations for C++

機能テストマクロの提案。C++17機能に対応するマクロが追加されている。

[PDF注意] N4441: SG5: Transactional Memory (TM) Meeting Minutes 2015-03-23 and 2015-04-06

トランザクショナルメモリーの会議の議事録。

N4442: Default argument for second parameter of std::advance (Rev. 1)

std::advanceの第二引数にデフォルト実引数として1を追加する提案。

std::advance( iter, 1 ) ;

のかわりに、

std::advance( iter ) ;

と書ける。

N4443: Introducing alias size_type for type size_t in class std::bitset (Rev. 1 )

std::bitsetにネストされた型名™size_typeを追加する提案。

他のコンテナーとあわせることで、ジェネリックなコードやポータブルなコードを書きやすくなる。

N4444: Linux-Kernel Memory Model

現行のC/C++のメモリーモデルがLinuxカーネル開発者のお気に召さなかった問題を受けて、Linuxカーネルのメモリモデルをまとめた文書。

Linuxカーネルのメモリモデルについて解説した文書。前回のN4374からの変更点はREAD_ONCE()とWRITE_ONCE()マクロの解説。

N4445: Overly attached promise

promiseに共有状態を管理するためのリソースを破棄させるメンバー関数、resetとreleaseの追加。

あるpromiseオブジェクトを使ったとする。

std::future<int> f()
{
    std::promise<int> p ;
    auto future = p.get_future() ;
    p.set_value( 42 ) ;

    // これ以降、promiseは使わない

    // 何らかの時間のかかる処理

    // promiseオブジェクトが破棄される
    return future ;
}

上記の例では、何らかの時間のかかる処理をしているあいだ、promiseオブジェクトは生きている。すると、共有状態を維持するためのリソースも破棄されないまま維持されてしまう。リソースの制約の厳しい環境では、このような不必要なリソースを早期に破棄したい需要がある。

現行規格でも、ムーブを使えばリソースの破棄は可能だ。以下のような方法でpromiseのオブジェクトpをムーブさせてリソースを開放させられる。

p = std::promise<int>{} ; // これでもよい。
std::promise<int>( std::move(p) ) ; // こちらのほうがわかりやすい

しかし、どちらも冗長でわかりにくい。N4445では、promiseから共有状態のリソースを破棄するためのメンバー関数、resetとreleaseを追加する提案をしている。

releaseは共有状態の破棄。resetは空のpromiseとswapをしたかのように働く。

N4446: The missing INVOKE related trait

ある型がある並びの引数の型で関数呼び出しできるかを調べるis_callableの提案。

より厳密に説明すると、N4169で入ったinvokeが未評価オペランドにおいて合法かどうかを確かめる。is_callableの提案。

template <class, class R = void> struct is_callable; // not defined
template <class Fn, class... ArgTypes, class R>
  struct is_callable<Fn(ArgTypes...), R>;

たとえば、is_callable< F ( A0, A1, A2 ) >::valueは、std::invoke< F, A0, A1, A2>が合法の場合にtrueを、substitutionに失敗する場合にfalseを返す。

void f( std::string, std::vector ) ;

constexpr bool b = std::is_callable_v< decltype(&f) ( std::string, std::vector) > ;

[PDF注意] N4447: From a type T, gather members name and type information, via variadic template expansion

「型Tからメンバー名と型情報をVariadic Templates展開で得る」という、なんとも説明的で実用的なタイトルの提案論文。内容として派生的リフレクション機能だ。

その提案内容も極めて実用的だ。typedef<T, C>, typename<T, C>, typeid<T, C>という文法を追加する。Tはクラス型で、Cはコンセプトか型名で、constexpr operator ()でbool値を返す。trueを返したメンバーだけが展開される。

その動作は、サンプルコードを見たほうが良い。


using namespace std;

namespace ns {
    struct X {
        int x, y;
    };
}

vector<std::string> names{ typeid<ns::X, is_member_object_pointer>... };

tuple<typename<ns::X, is_member_object_pointer>...>
    mytuple = make_tuple(typedef<ns::X, is_member_object_pointer>...);

最後の二行のコードは、コンパイラーによって以下のように変換される。

vector<string> names { "x","y" };

tuple<ns::X::int, ns::X::int>
    mytuple = make_tuple(
        &ns::some_struct::x,
        &ns::some_struct::y);

この提案は新しいキーワードを必要としないしASTコントロールも必要としないし特別なコンパイラーマジックやライブラリーも必要としない。

用途は、シリアライゼーション、メタプログラミング、型変換、イベント駆動開発。テスト駆動開発、GUIプロパティエディター、データベースオブジェクトのマッピングインターフェース、ドキュメントの自動化、コンセプトの自動チェック、コンストラクターのリフレクション。

まあ、便利だとは思うのだが、なんとも低級な機能だ。

N4448: Rounding and Overflow in C++

演算の結果の丸めとオーバーフローの挙動を規定できるライブラリの提案。

丸めモードにはすでにfenv.hがあるが、これは不十分だとしている。

丸めモードに対しては、以下の挙動が提案されている。

enum class rounding {
  all_to_neg_inf, all_to_pos_inf,
  all_to_zero, all_away_zero,
  all_to_even, all_to_odd,
  all_fastest, all_smallest,
  all_unspecified,
  tie_to_neg_inf, tie_to_pos_inf,
  tie_to_zero, tie_away_zero,
  tie_to_even, tie_to_odd,
  tie_fastest, tie_smallest,
  tie_unspecified
};

fastestは実行速度優先。smallestは誤差最小優先。

関数には、convertと、divideとrshiftが用意されている。

オーバーフローには、以下の挙動が提案されている。

enum class overflow {
  impossible, undefined, abort, exception,
  special,
  saturate, modulo_shifted, modulo_dividend, modulo_divisor, modulo_positive
};

impossible: オーバーフローは起こりえない。これを指定したプログラムは厳格な検証によりオーバーフローがー起こりえないことを証明すること。

undefined: オーバーフローはまれにしか起こらないので考えなくてよい。

abort: オーバーフローが起きたらabortする。検出が必要。

exception: オーバーフローが起きたら例外を投げる。検出が必要。

special: オーバーフローが起きたら特別な値を返す(IEE浮動小数点数など)

saturate: オーバーフローが起きたら妥当な範囲の値で最も近いものを返す。

オーバーフローを指定できる関数には、convertの他に、limit( lower, upper value )とその派生版と、lshiftが提案されている。

最後に、丸めとオーバーフローを両方取るconvertとbshiftが提案されている。

N4449: Message Digest Library for C++

暗号に使える強度を持ったハッシュ関数ライブラリの提案。

「設計はPythonのhashlibモジュールから恥ずかしげもなくパクった」

まだ文面が不完全だが、Pythonのhashlib風のインターフェースになっている。

ドワンゴ広告

どうやら弊社では、自社から出た最新の参考書を自腹で買う社員が多いようだ。他ならぬKnuth本ならば仕方あるまい。しかし、ご存命のうちに完成するのだろうか。

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

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

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

4 comments:

Anonymous said...

最近の提案はどんどんブラックマジックを要求するものが増えてきていると思います。
自分の理解が追いついてないだけなのですが、ちょっと一口に実装が見えないようなものをホイホイ導入していく姿勢にはちょっとついていけない部分があります。
やっぱ、アマチュアには厳しい世界ですね。

Anonymous said...

ネストされた型名™

Anonymous said...

社割り効かないんですか?

Anonymous said...

トランザクショナルメモリってどうやって実装するんですかね。
現実を考えても、トランザクションキャンセルって相当めんどくさいと思うのですが。
小人さんは優秀だなー。