2016-09-12

C++標準化委員会の文書: P0400R0-P0409R0

P0400R0: P0400R0 2016-06-25

C++17では式の評価順序が、関数の引数を除いて固定された。関数の引数の順序は未だに不定だが、その部分の文面がわかりにくく書かれているため、書き直しの提案。

P0401R0: Extensions to the Allocator interface

アロケーターに確保したストレージの実サイズも返すallocate関数の追加の提案。

アロケーターの実装として、32バイトとか64バイトなどの固定サイズごとのチャンク単位でメモリを管理して、要求されたサイズに最も近いチャンクサイズに切り上げてメモリを返す方法がある。

そのような戦略を取るアロケーターに対して、例えばvectorが36バイトのメモリを要求して、実際には切り上げて64バイトが割り当てられたとする。その後、vectorは52バイトのメモリを要求する。アロケーターは64バイトの別のチャンクメモリを返す。vectorは既存の36バイト要求に対して割り当てられた64バイトのメモリの値を、新しい52バイト要求に対して割り当てられた64バイトのメモリにコピーして、古い方の64バイトのメモリを開放する。

この時点で気がつくように、vectorのこの操作は、メモリに実際に割り当てられるサイズを知っていれば、本来不要であり、除去できるものである。しかし、現行のアロケーターには、メモリの実サイズを得る方法がない。

そこで、以下のような関数を新たに追加する。

pointer allocate(size_type n, size_type& result, const_void_pointer hint = {});

resultに対して、実際のサイズが書き込まれる。

これは純粋にアロケーターだけでの対応方法だ。reallloc風の機能には、コンテナー側での対応も必要になるので、この提案では取り扱わないとしている。

P0404R0: Matching Types: 404 Syntax Not found

文書番号がHTTP標準レスポンスコード404と偶然に同じで、文書のタイトルにも404へのリファレンスがある。

constexpr ifが追加された今、C++に必要なのは型パターンマッチだ。ということで極めて不自然な文法で型に対するパターンマッチを提案している。文法が既存のC++からみると違和感がありすぎる。

これはダメだ。

P0405R0: Wording for Networking TS changes discussed in Kona

ネットワークTS、ネットワークライブラリに対する細かい修正案

[PDF] P0407R0:Allocator-aware basic stringbuf

stringbufに近代的なアロケーターサポートを追加する提案。

stringbufはC++の歴史の上でもかなり早い段階で追加されたライブラリのため、近代的な設計になっていない。アロケーターはテンプレートパラメーターとしてしか渡すことができず、オブジェクトとして渡すことができない。このため、stringbufのオブジェクトごとのアロケーター指定ができない。

この提案では、basic_stringと同等のアロケーターサポートを追加する。

iostreamの設計は根本的に失敗なので、iostreamを改良する労力は無駄であると思う。

[PDF] P0408R0: Efficient Access to basic stringbuf's Buffer

stringbufとstringstreamには、内部のバッファーをコピーせずに参照する方法が一切ない。そのため、本来不要なコピーが発生していた。

std::stringstream ss ;
// コピーが発生する
ss << "hello" ;

std::string result ;
// コピーが発生する
ss >> result ;

そのため、この提案ではコピーを回避してstringbufと、stringbufを使うstringstreamの内部バッファーを直接アクセスする方法を提供する。

まず、コンストラクターにbasic_stringへのrvalueリファレンスを取るオーバーロードが追加される。これによって、初期値をコピーなしで与えることができる。

std::string const initial_value("hello") ;

// ムーブされる
std::stringstream ss( std::move( initial_value ) ) ;

std::string const another_value("123 456 789") ;

// ムーブされる
// 後でコピーを回避して値を変えることもできる
ss.str( std::move( another_value ) ) ;


// string_viewを返す
// コピーせずにリードアクセスできる
auto view = ss.str_view() ;

// stringを返す
// コピーではなく内部バッファーがstringにムーブされる
auto str = std::move(ss).str() ;

確かに有益だが、iostreamをこれ以上付け焼き刃で改良するのに労力を咲くのはやめて、もっとまともな文字列処理ライブラリと入出力ライブラリを作るべきだ。

P0409R0: Allow lambda capture [=, this]

[=,this]を許可する提案。

lambda captureのdefault captureに=が指定された場合、後続するキャプチャーには、リファレンスキャプチャーしかかくことができない。thisはthisポインターの値キャプチャーなので、当然書くことはできない。

int x{} ;
// エラー
[=, x] { } ;

class C
{
    C()()
    {
        // エラー
        [=,this]{} ;
    }
} ;

問題は、C++17には、thisポインターの参照先、つまり*thisを値キャプチャーするための文法が入った。

[*this] { } ;

これにより、クラスへのポインターではなく、クラスオブジェクトである*thisがクロージャーオブジェクトにコピーされる。

つまり、以下のようなキャプチャーが書ける。

[=,*this]{} ;

このような記述が増えると、[=,*this]と区別して、]thisポインターをキャプチャーすることを明示するために、[=.this]と書きたくなる。これは基本的に良い作法であると思われるので、そのような記述を出来るように制限を緩和する。

ドワンゴ広告

<meta name="description" content="ここに変な文字列を突っ込みながら特定のWebサービスについて運営で参考にされるほど真面目に考察することで、運営の使っているURL先のmetaタグを読んで埋め込み表示するチャットシステムのログにシュールな雰囲気をもたらすハック">

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

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

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

1 comment:

Anonymous said...

もしかして、関数ポインタにthis持ちのラムダを束縛できるようになるんでしょうか?だったらいいなー。