本の虫

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

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

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

2014-07 post Rapperswil mailingのレビュー: N4070-N4079

またもや次の論文10本

N4070: Improving the specification of the vector execution policy in Parallelism TS

Parallel TSのベクトル実行アルゴリズム内で実行される関数が同期をすることは禁止されている。しかし、標準ライブラリの関数のうち、同期を行わない保証のある関数なのかということは、明記していない。

これを解決するために手始めにそのことを警告する文面を追加する提案。

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

C++のアルゴリズムに並列実行と並列ベクトル実行版のオーバーロードを追加して拡張するTSのドラフト。

従来のアルゴリズムに、タグを指定することで、シーケンシャル実行、並列実行、並列ベクトル実行を切り替えることができる。

// N4071提案
#include <experimental/execution_policy>
#include <experimental/algorithm>

template < typename Iterator >
void f( Iterator first, Iterator last )
{
// シーケンシャル実行
    std::stable_sort( std::seq, first, last ) ;

// 並列実行
    std::stable_sort( std::par, first, last ) ;

// 並列ベクトル実行
    std::stable_sort( std::par_vec, first, last ) ;
}

N4072: Fixed Size Parameter Packs

パラメーターパックの個数を指定できる機能、固定数パラメーターパックの提案。

// N4072提案

// argsは個数3、型はint型
void f( int ...[3] args ) ;

// argsの個数は3
template < typename ... Types >
void g( Types ... [3] args ) ;

// Argsの個数は3
template < typename ...[3] Args >
void h( Args ... args ) ;

T ...[N] pは、N個のT型のパラメーターパックpである。Nは定数式でなければならない。

いったいこの機能何に使うのか。論文では、いくつかの利用例を挙げている。

指定した個数の実引数を取りたい場合を考える。

struct my_vector3 {
    // ...
    my_vector3(int x, int y, int z)
        : values{x, y, z} {}
};

こんなクラスがあるとする。my_vector4とかmy_vector10などを手で書くのではなく、my_vector<N>のように、テンプレートで個数を指定したい。

実は、これは現行のC++14の枠内で行うのは、とてつもなく面倒で長ったらしいコードを書かなければならない。しかし、固定数パラメーターパックがあれば、以下のようにあっさりと書ける。


template<unsigned int N>
struct my_vector {
    // ...
    my_vector(int...[N] v) : values{v...} {}
};

指定した個数のある型の引数を取りたい。

void foo3( int, int, int )のような関数があるとする。ここで、foo4のような関数を手で書くのではなく、foo<N>のように、テンプレートで個数を指定したい。

しかし、これをC++14で簡潔に書く方法がない。固定数パラメーターパックならば、以下のように簡潔に書ける。


template<unsigned int N>
void foo(int...[N] v);

あるいは、単に機械的なパターンを手で書く代わりに使うこともできる。


void foo(int x, int y, int z, int w) { do_magic(x, y, z, w); }

template<typename A, typename B, typename C, typename D, typename E>
void bar(A a, B b, C c, D d, E e);

のような機械的なパターンのあるコードは、


void foo(int...[4] v) { do_magic(v...); }

template<typename...[5] T>
void bar(T... v);

このように書くことができる。

この提案では、実引数推定で、固定数を推定することができる。

例えば、以下のような例は実引数推定できる。

template < unsigned int N >
void f( int ... [N] ) { }

f( 1, 2, 3 ) ; // Nは3と推定される

template<unsigned int N> void f(int, int...[N]) {}
f(1,2,3); // Nは2と推定される

template<unsigned int N, unsigned int M> void f(int...[N], int...[M]) {}
f<2>(1,2,3); // Mは1と推定される。Nは推定できないが、明示的に指定されている

例えば、以下のような場合は、固定数パラメーターパックで実引数推定できない。


template<unsigned int N> void f(int...[N], int) {}
f(1,2,3);

template<unsigned int N> void f(int...[N], int...[N]) {}
f(1,2,1,2);

template<unsigned int N> void f(int...[N*2]) {}
f(1,2,3,4);

[暗い未来を予感させるPDF] N4073: A Proposal to Add 2D Graphics Rendering and Display to C++

C++の標準ライブラリグラフィックライブラリを追加することに対する考察と提案。cairoに機械的な変換を書けてC++風の設計にしている。

[Let PDF-writer die in agony] N4074: Let return {expr} Be Explicit, Revision 2

return {expr}の意味を、return-type var {expr} ; return var ;と同じ意味にしようという提案。

以下のようなコードを考える。

struct very_long_type_name
{
    explicit very_long_type_name(int) { }
} ;

very_long_type_name f()
{
    return { 0 } ; // ill-formed 
}

このコードを合法にする提案だ。

return文のオペランドを{}で囲んだ場合、戻り値の型のローカル変数を直接初期化して返すのと同等の効果にしようという提案である。

関数の戻り値の型と、その関数内のreturn文とは、関数の中だけの話だから、十分に明示的である。{}で囲むというのも明示的である。

very_long_type_name f()
{
    return very_long_type_name{0} ;
}

これはいかにも冗長だ。

[無駄にPDF] N4075: Centralized Defensive-Programming Support for Narrow Contracts (Revision 5)

防衛的プログラミングと称し、assertマクロの高級版を追加する提案。

assertに引っかかった時の挙動を指定できたり、テストできたりと、色々と高機能だが、Cプリプロセッサーマクロを使うという時点で、筆者は反対する。

N4076: A proposal to add a generalized callable negator (Revision 4)

汎用的なnegator、not_fnの提案。

not1やnot2は引数がひとつか二つのとても制約の強い関数オブジェクトしからっぷできなかった。not_fnは、Variadic Templatesや最近のメタプログラミング技法を使い、任意個の引数を取る任意の呼び出し可能なオブジェクトをラップできる。

// N4076提案
auto f() { return true ; }

int main()
{
    auto n =  std::not_fn(f) ;
    n() ; // false
}

N4077: Experimental shared_ptr for Library Fundamentals TS

TSに提案されるライブラリが使うために、実験的なshared_ptr実装である<experimental/memory>と、独立したshared_ptr, weak_ptr, owner_less, enable_shared_from_thisの提案。

詳しい経緯はN4041にかかれているが、TS用の拡張として既存の標準ライブラリを使う場合、サードパーティによる規格準拠の実装が作れないという問題がある。そこで、規格準拠な実験的実装を行えるように、必要な標準ライブラリを、同一機能であるが、別ヘッダー、別名前空間の別ライブラリとして定義する提案。

N4078: Fixes for optional objects

Issaquah会議で指摘された、Optionalのドラフト文面に存在する問題の修正。どれも小粒な文面上の修正となっている。

N4079: C++ Standard Library Issues Resolved Directly In Rapperswil, 2014

rapperswil会議で修正された標準ライブラリに持ち上がっている問題集。

些細な文面上の誤りの修正が多い。

ドワンゴ広告

この記事はドワンゴ勤務中に書かれた。

今日は都合で、いつもとは違い丸ノ内線に乗って通勤したが、明らかに周囲の背広集団から浮いている変わった服装と目立つ話し方をする人間を見かけた。銀座駅で降りて会社に向かったが、エレベーターの中で再開した。みると、ドワンゴの社員証を首から下げている。

さては同僚であったのか。

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

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

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