2016-07-14

C++標準化委員会の文書: P0280R0-P0289R0

P0280R0: Initialize unspecified aggregate members with direct list initialization

以下のコードのコンパイルが通るようになる変更。


struct S
{
    explicit S(int a = 0) : _a{a} { }
    int _a;
};

int main()
{
    S s ; // OK
    S arr[2] = { S{} }; // エラー
}

現行の文面ではコンパイルが通らないが、これはコンパイルが通ることが望ましい。

P0281R0: Remove comma elision in variadic function declarations

昔ながらの可変引数関数でコンマを書かずにellipsisを書ける昔ながらの文法を除去する提案。

以下は合法なC++のコードである。


int f( ... ) ; // 1
int f( int i, ... ) ; // 2
int f( int i ... ) ; // 3

1はポータブルな方法で可変引数を取り出すことができない。どんな引数でも受け付けるので、メタプログラミングではよく使われている。

2は通常使う関数の宣言

3は歴史的経緯により今だに認められている2と同等の意味を持つ関数の宣言。iと...の間にコンマを記述していない。

この文書は、3の文法をC++から除去する提案を行っている。この文法はユーザーの混乱の元であり、Variadic Templatesとの文法の曖昧性が発見されていて、将来の言語拡張の妨げにもなるので、廃止するのが望ましいとしている。

例えば、以下のコードは極めて紛らわしい。

template <class... T> void f(T...); // パラメーターパックを引数に取る関数
template <class T> void f(T...);    // T型と可変引数を取る関数

現行のC規格ではコンマ省略が認められていないので、C言語との互換性の問題はない。

[PDF] P0283R1: Standard and non-standard attributes

実装がサポートしていないattribute namespaceは無視するように注釈を付け加える提案。

現行規格は、実装がサポートしていないattributeに対してどのように振る舞うべきか規定していない。実装がサポートしていないattributeに対してコンパイルエラーを出す場合、ユーザーはattributeをマクロで隠すようになる。これではattributeの存在意義が否定されてしまう。そのため、実装がサポートしていないattribute namespaceは無視すべきである。

[[ezoe::foobar]] int i ; // attributeは無視する

P0284R0: Unqualified enumerators in case labels

switch文のconditionがenum型の場合、そのswtich文に属するcase文では、unqualified lookupでenumeratorが見つけられるようにする提案。

以下のコードが、

enum struct E
{
    foo, bar 
} ;

void f( E e )
{
    switch( e )
    {
    case E::foo :
        break ;
    case E::bar :
        break ;
    }
}

以下のように書けるようになる。

enum struct E
{
    foo, bar 
} ;

void f( E e )
{
    switch( e )
    {
    case foo :
        break ;
    case bar :
        break ;
    }
}

これはぜひともほしい変更だ。switchのconditionがenum型であることがわかっているのだから、非修飾名でもenumeratorが見つけられるべきだ。

P0285R0: Using customization points to unify executors

ユーザー定義のexecutorを渡すcustomization pointを設ける提案。

customization pointとは、std名前空間の下に関数テンプレートがありデフォルトの実装がされている。unqualified nameで呼べばADLによって優先されるように書いておけばそちらが優先される。という仕組み。

P0286R0: A networking library extension to support co_await-based coroutines

ネットワークライブラリをco_awaitに対応させる変更の提案。

[PDF] P0287R0: Simple Contracts for C++

contractサポートの提案。preconditionとpostconditionのみに限定している。attributeで関数宣言に記述できる。

だいたい以下のような形になる。

template < typename T >
class array
{
// データメンバーなど
public :
    std::size_t size() ;

    value_type & operator []( std::size_t i )
    [[ expects: i < size() ]] ;

    void resize( std::size_t n )
    [[ ensures: size() == n ]] ;

} ;

機能的には、assert( condition )を関数の前後に挟むのと大して変わらない。プリプロセッサーマクロではなくコア言語によるサポートがあることと、コア言語でサポートされるので、コンパイラーオプションなので有効無効を切り替えられる実装にできるぐらいか。

文書はもうひとつ、[[ assert : condition]]を提案している。

[PDF] P0288R0:A polymorphic wrapper for all Callable objects

unique_functionの提案。std::functionとほぼ同じだが、コピーコンストラクター、コピー代入演算子がない。そのため、コピーできないcallable型を格納できる。

[PDF] P0289R0: Forward declarations of nested classes

ネストされたクラスの前方宣言を認める制限緩和をする提案。以下のように書けるようになる。

class X::A ;
X::A ptr = nullptr ;

現状では、以下のように書かなければならない。

class X
{
    class A ;
} ;

ネストされたクラスの宣言を囲む直前のクラスの定義の中で宣言しなければならない。不完全型のX::Aしか必要ない場面でも、完全型のXが必要になる。つまり、Xの定義が必要になる。

この制限緩和をする提案。

ドワンゴ広告

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

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

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

2 comments:

Anonymous said...

swtchの変更が魅力的ですね。親を記述しなければいけなかったのは確かにタイプ量が上がってめんどくさかったです。まぁ、コードサジェストで引っ掛けて多少楽はできましたが、ちょっと冗長には感じていました。修正されるなら歓迎します。
契約もそれなりにほしいですね。書くのが面倒ですが、フォーマルな場面でよさそうです。

Anonymous said...

class X::A ; は是非とも欲しいところ。
論文では書かれてませんが、enum class X::E : int ; みたいなのは需要がありそうですね。