2015-05-27

C++標準化委員会の文書 2015-04 Pre-Lenexaのレビュー: N4400-N4409

N4400: Concurrency TS Editor's Report, April 2015

N4399 Concurrency TSドラフトの編集者による変更点の記述

N4401: Defaulted comparison operator semantics should be uniform

現在、特別なメンバー関数としてデフォルトの比較演算子を生成する機能を追加しようという提案が出ているが、その提案では、ポインターとmutableな型のデータメンバーに対してはデフォルトの比較演算子を生成しないとしている。その理由は、ほとんどの場合でユーザーの意図しない結果となるだろうからとのことだ。

この論文は、ポインターの比較方法はすでに厳密に定義されていてプログラマーも了解しているし、既存の特別なメンバー関数であるコピーコンストラクターは、ポインターだろうがmutableだろうがお構いなしにそのままコピーすることを引き合いに出し、これ以上特別なルールを付け加えることは無用の混乱を招くだけであるし、結果が利用者の意図した通りでないのは利用者の責任であるとして、その方針に反対している。

N4404: Extension to aggregate initialization

C++11のアグリゲート初期化は便利だ。


struct user
{
    uint32_t id ;
    std::string name ;
} ;

user u{ 10, "Alice" } ;

しかし、アグリゲート初期化は、基本クラスを持つ型には使えない。

struct common { } ;

struct user : common
{
    uint32_t id ;
    std::string name ;
} ;

user u{ 10, "Alice" } ;

この場合、従来通りコンストラクターを手で書かなければならない。

struct user : common
{
    uint32_t id ;
    std::string name ;

    user( uint32_t id, std::string name )
        : id(id), name(name) { }
} ;

user u{ 10, "Alice" } ;

これは明らかに面倒だから、基本クラスがdefault constructibleな場合ならば、アグリゲート初期化を使えるようにしようという提案。

N4405: Type of the accumulaters of standard algorithms std::accumulate and std::inner_product

ロシア人によって書かれたためか英語が少し拙い。

標準規格では、std::accumulateとstd::inner_productの内部の作業中の変数の型が明記されていない。これにより、実装に差が生じ、同じコードが実装によって通ったり通らなかったりする。

例えば、std::accumulateが以下のような実装になっている場合、


template <class InputIterator, class T>
T accumulate( InputIterator first, InputIterator last, T init )
{
 T acc = init; // 作業用の変数

 for ( ; first != last; ++first ) acc = acc + *first;

 return acc;
}

以下のようなコードは通らない

std::accumulate<decltype( std::begin( a ) ), const int>( std::begin( a ), std::end( a ), 0 ) ;

しかし、もし実装が、

auto acc = init ; // 作業用の変数

のようになっている場合、このコードは通る。

また、利用者は値のコピーを防ぐために、リファレンスを明示的に使うかもしれない。

long long aac = 0 ;
std::accumulate< decltype( begin(a) ), long long & >( begin(a), end(a), acc ) ;

これも、実装によっては通ったり通らなかったりする。

実装の差異を防ぐために、内部の変数の型について、規格で規定しなければならない。

提案では、内部の変数の型は、あたかもT accのように宣言され、初期値で初期化される。Tにはリファレンス型もありえるという文面を提案している。

N4406: Integrating Executors with Parallel Algorithm Execution

Parallelism TSとして、並列実行版アルゴリズムが提案されている。この提案は、並列実行が「どのように」行われるかを支持することはできるが、「どこで」行われるかを支持することはできない。

並列実行の方法には様々なものがあり、その方法を、実行媒体(execution agent)と呼ぶ。OSの提供するネイティブのスレッドもあれば、ファイバーのような協調的マルチタスクを用いた軽量スレッドもある。他にも、SIMDやGPGPUのような実行媒体もある。この提案は、具体的な実行媒体を扱うexecutorをParallelism TSに導入する提案をしている。

executorは共通のAPIを持つ。executorはどのような実行方式なのかを指し示す実行カテゴリーを持つ。executorは実行媒体を大量に確保するために、単一の呼び出しで多数の実行媒体を確保する方法を提供する。標準で提供されることが保証されている標準executorを用意する。実行を簡単に行える方法を提供する。

実行カテゴリーとして提案されているのは、シーケンシャル実行、並列実行、ベクトル実行。

標準executorとしては、シーケンシャルexecutorと並列executorとベクトルexecutor。また呼び出し元のスレッドで実行される版の並列/ベクトルexecutorもある。

N4407: Technical Specification for C++ Extensions for Parallelism, Working Draft

Parallelism TSのドラフト

並列実行版のアルゴリズムライブラリ

N4408: Parallelism TS Editor's Report

Parallelism TSドラフトの編集者による変更点の記録。今回はレイアウトの調整程度らしい。

N4409: Programming Languages -- Technical Specification for C++ Extensions for Parallelism

内容はN4408とほぼ同じ。

ドワンゴ広告

特に書くことがないが、今日はボドゲをせずに溜まったC++標準化委員会の文書を片付けている。

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

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

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

1 comment:

Anonymous said...

エグゼキュータの話ですが、こういうものはベースクラスを作ってインターフェースを定義した上で継承かんけいにある上位を定義したほうがいいかもしれないですね。
各種エグゼキュータを関数に投げたい用途ってままあると思うのですが、まぁ、インターフェースクラスが定義されていないと投げられませんので。
関数を無駄に書くのは絶対嫌でう。
こういう、多様性を出すためのベースクラスって結構大事だと思います。
まぁ、ガンというなら一回定義したら変えるのが大変ということですね。
で、なんでもTにしてしまえばいいやっていうのもある種のガンなので制裁を加えたいですね。
お前ら量子嫌いだからBASIC破棄したんだろーとか私怨持っちゃいます。さて、何のことでしょうかね・・・。Orz

まぁ、フレーム構築には結構そういうインターフェースを多用するのでなんかそういうレールがほしいです。