本の虫

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

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

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

2018 Jacksonville会議でC++のドラフト入りが決定した機能

2018 Jacksonville ISO C++ Committee Reddit Trip Report : cpp

なぜこのような情報をRedditで見なければならないのかという疑問はあるが、2018 Jacksonville会議の結果がRedditでまとめられている。

P0840R1: Language support for empty objects

[[no_unique_address]]属性が追加された。この属性はクラスの非staticサブオブジェクトがユニークなアドレスを必要としないとコンパイラーに支持するものだ。これによって、コンパイラーはそのサブオブジェクトにメモリレイアウト上でスペースを割り当てる必要がなくなるので、Empty Base Optimizationができる。

struct A { } ;
struct B { } ;
struct C { } ;

struct D
{
    [[no_unique_address]] A a ;
    [[no_unique_address]] B b ;
    [[no_unique_address]] C c ;
} ;

int main()
{
    // 1
    std::cout << sizeof(D) ;
}

例えばtraitsのようなクラスのサブオブジェクトとして持っておくのに使える。

template<typename Key, typename Value,
         typename Hash, typename Pred, typename Allocator>
class hash_map {
  [[no_unique_address]] Hash hasher;
  [[no_unique_address]] Pred pred;
  [[no_unique_address]] Allocator alloc;
  Bucket *buckets;
  // ...
public:
  // ...
};

P0634R2: Down with typename!

文脈上、型しか書けない場所に書かれたものは型であるとみなすことにより、依存名にtypenameを記述しなくてもすむように制限緩和する提案。

依存名が型である場合はtypenameキーワードによって型であることを明示しなければならない。


// Tはこんな感じの型を想定
struct example
{
    using type = int ;
    static constexpr type value = 0 ; 
} ;

// 
template < typename T >
typename T::type f()
{
    typename T::type x = T::value ;
    using type = typename T::type ;
    std::vector< typename T::type > v 
    return x ;
}

このコードが以下の様に書けるようになる。


template < typename T >
// typenameはいらない
T::type f()
{
    // typenameが必要
    typename T::type x = T::value ;
    // typenameはいらない
    using type = T::type ;
    // typenameはいらない
    std::vector< T::type > v 
    return x ;
}

書きやすくなった。

P0479R4: Proposed wording for likely and unlikely attributes (Revision 4)

[[likely]]と[[unlikely]]の追加。この属性は文に書くことができる。この属性が書かれた文を含む実行パスの実行の期待度を示す。

例えば以下のようなコードがあるとして、


while ( true )
{
    // まれにしか起こらないエラーのチェック
    if ( check_rare_error_condition() ) {
        // 分岐1
        // エラーへの対処
    } else {
        // 分岐2
        // 通常の処理
    }
}

このコードでは、エラーが起こることはまれであり、したがって分岐1が実行される可能性は低い。コンパイラーがその情報を事前に知っていれば、コード生成の際に役立てることができる。


    if ( check_rare_error_condition() )
    {
        [[unlikely]] ;
        // エラーへの対処
    }

この機能は大抵のコンパイラーが独自拡張として様々な文法ですでに実装している。

[PDF] P0754R1: version

ヘッダーファイル<version>を追加。このヘッダーファイルは標準規格的には何も入っていない。実装依存のバージョン番号やリリース番号を示す定義済みマクロを提供するためのヘッダーファイルだ。

多くのC++コンパイラーが独自の定義済みマクロでコンパイラーのバージョンその他の情報を提供している。問題は、そのような定義済みマクロは、コンパイラーマジックによって定義されるのでもなければ、なんらかの標準ライブラリのヘッダーファイルを読み込まないと定義されない。

そこで、標準ライブラリの中でも特に軽量なヘッダーファイルである<ciso646>が慣習的に使われてきたが、今回、ciso646は実用的な機能を提供していないので廃止しようという議論が持ち上がった。そこで、このヘッダーファイル自体に意味はないが、コンパイラー独自の定義済みマクロのためだけに#includeしている既存のコードがたくさんあるという指摘が上がった。

そのため、その用法をサポートするための最も軽量なヘッダーファイルである<version>が提案され、追加された。

P0355R5: Extending <chrono> to Calendars and Time Zones

<chrono>にカレンダーライブラリの追加。

int main()
{
    auto date = 2017y/mar/18d ;
    // "2018-03-18"
    std::cout << date ;
}

カレンダー操作が型安全に行える。

[PDF] P0753R1: placeholder

osyncstream用のバッファーフラッシュの動作を制御するマニピュレーターの追加。

[PDF] P0122R6: placeholder

連続したストレージを所有しないまま配列として扱うspanライブラリの追加。提案段階ではarray_refとかarray_viewなども提案されていたが、最終的にspanになった。

P0780R1: Pack expansion in lambda init-capture

ラムダ式の初期化キャプチャーでパック展開ができるようになった。これにより可変長テンプレートを使った関数テンプレートでラムダ式にパラメーターパックをそれぞれムーブキャプチャーすることができるようになった。

template < typename ... Types  >
void f( Types ... args )
{
    [ args = std::move(args)... ](){} ;
}

ドラフトの変更以外としては、simd<T>がParallerism TS v2に入ったり、Reflection TS v2, Library Fundamentals TS v3が発行されたりした。

現在の観測を見てみると、モジュールがC++20に入るかは疑わしい。コンセプトとレンジのコアは入りそうだ。

colony(歯抜けを許すvector)やflat_map(ソート済みvectorのバイナリサーチ)はC++20に入ってほしい。他には、fixed_capacity_vector(サイズ固定vector)やring_span(リングバッファー)

ドワンゴ広告

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

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

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