2010-02-18

pre-Pittsburgh mailingの簡易レビュー

ISO/IEC JTC1/SC22/WG21 - The C++ Standards Committee

pre-Pittsburgh mailingが公開された。なぜか、今現在は、post-Santa-Cruz mailingになっているが、これは間違いである。中身はpre-Pittsburghである。

現在のワーキングドラフトは、N3035となった。

N3021: Harmonizing Effects and Returns Elements in Clause 21

String Libraryの個々のメンバー関数の定義で、[structure.specifications]の定めるところの、EffectsとReturnsの使い方がなされていない。具体的な例を出すと、たとえば、string::operator +=の場合、

Returns: append(str).

となっている。つまり、現状ではReturnsだけで、Effectsも定義している。これを、[structure.specifications]が定めるところにより、正しく定義しなおす。具体的には、Returnだけで定義されていたものを、EffectsとReturnsに分離する。また、必要に応じて、その他の句も付け加える。

Effects : Calls append(str.data(), str.size()) .
Returns: *this.

N3023: Defaulting non-public special member functions on first declaration

特別なメンバー関数を、非publicに明示的なデフォルト化(explicitly-defaulted)できないという問題への対処。つまり、

struct Foo
{
// 暗黙に宣言されるデフォルトコンストラクタをprotectedにする。
protected :
    Foo() = default ;
// 暗黙に宣言されるコピーコンストラクタをprivateにする。
private :
    Foo( Foo & )  = default ;
} ;

このコードは、現状ではill-formedである。しかし、上記のようなコードは利点があるので、特別なメンバー関数は、明示的に非publicにデフォルト化できるべきである。という提案。

N3024: Proposal to Simplify pair (rev 4)

pairが複雑になりすぎているから、少し単純化しようという提案の、改訂版。

N3025: Specifying Pointer-Like Requirements

規格の複数の箇所で、型が、nullableかつpointer-likeであることが要求される。個々の場所で要求するよりも、そのようなrequirements、NullablePointer requirementsを追加し、参照するという提案。

N3030: Rvalue References as "Funny" Lvalues

lvalueを二種類に分ける。すなわち、従来のlvalueを、non-rref lvalueとし、ある特殊な値を、rref lvalueとする提案の改訂版。rref lvalueは、以下の場合の式によって生成される。

  • Function calls (explicit or implicit) that return rvalue references to objects
  • Casts to rvalue references to objects
  • Member selection and pointer-to-data-member dereference expressions where the object expression is an rref lvalue

N3031: Core issues 743 and 950: Additional decltype(...) uses

あのウメハラとガチで戦えるイケメンのアキラさんによって報告された、我らがC++WG JPの誇るべきコメントJP 8 (Core issue 743)の、decltypeをname qualifierとして使用できるようにする提案。また、base-specifierや、pseudo-destructor-name、mem-initializer-idにも使用できる。

struct Base
{
        typedef int type ;
} ;

Base base ;
// well-formed. use decltype in a name qualifier.
decltype(base)::type ; 

// well-formed. use decltype in a base-specifier.
struct Derived : public decltype(base)
{
        // well-formed. use decltype in a mem-initializer-id.
        Derived : decltype(base)()
        { }
} ;

// well-formed. use decltype in a pseudo-destructor-name.
base.~decltype(base)() ;

見ての通り、名前修飾子はもとより、ベースクラスの指定や、メンバー初期化子の指定、疑似デストラクタ名にもdecltypeが使えるようになる。

N3032: Core issue 374: Explicit specialization outside a template's parent

名前通り、C++ Standard Core Language Active Issuesの374を参照のこと。以下のコードをwell-formedにする。

  namespace NS1 {
    template<class T>
    class CDoor {
    public:
      int mtd() { return 1; }
    };
  }
  template<> int NS1::CDoor<char>::mtd()
  {
    return 0;
  }

N3033: Core issue 951: Various Attribute Issues

attributeを記述できる場所の追加。また、記述する場所の変更。

N2024: Core issue 968: Disambiguating [[

Santa Cruz会議で、我々は、[[をすべて、attributeとみなすことに同意した。しかしながら、それではちとばかし困る場合がある。

int p[10];

void f()
{
        int x = 42;

// ill-formed.
// a lambda expression and function call in a subscripting.
// but standard assumes it as attribute.
        int(p[[x]{return x;}()]) ; 

// ill-formed.
// almost same. again standard assumes it as attribute.
        new int[[]{return x;}()] ;
}

これをwell-formedにしようという提案。

N3037: Conceptless Random Number Generation in C++0X

randomライブラリから、conceptがドラフトに入っていた名残を撤去。また、細かな変更。

N3038: Managing the lifetime of thread_local variables with contexts (Revision 2)

thread_local修飾された変数が、いつ破棄されるのかという問題がある。thread::join以外の以外の方法でスレッドの終了を待機した場合、thread_local修飾された変数は、まだ破棄されていない可能性がある。

それに、スレッドプールのような仕組みで、一度作ったスレッドを使いまわす場合、thread_local就職された変数を、ある地点で、生成破棄して、再びやりなおしたい場合がある。しかし、現在の標準では、それができない。

そこで、thread_local_contextクラスを追加する。これは、thread_localの寿命を指定するクラスである。このクラス自体を、直接操作することはない。このクラスのオブジェクトのlife timeが、すなわち、thread_localなオブジェクトのlife timeになる。どういう事かというと、

// スレッドごとに独立して、ひとつ存在するべきクラス。
classs Thread_Local_Object ;

// そのクラスのオブジェクト。
// このオブジェクトは、スレッドごとにひとつ、生成される。
thread_local Thread_Local_Object obj ;

// スレッド関数
void worker_thread()
{
        {
                // ここで、新たなコンテキストが始まる。
                // すなわち、objのコンストラクタが走り、新しいobjが生成される。
                std::thread_local_context context ;
                // 処理

        }// ここで、コンテキストが終わる。すなわち、objのデストラクタが走り、objが破棄される。


        {
                // ここで、新たなコンテキストが始まる。
                std::thread_local_context context ;
                // 処理

        }// ここで、コンテキストが終わる。すなわち、objのデストラクタが走り、objが破棄される。

        {// コンテキスト #1
                // ここで、新たなコンテキストが始まる。
                std::thread_local_context context ;
                // 処理

                {// コンテキスト#2 ネストできる。
                        // ここで、新たなコンテキストが始まる。
                        std::thread_local_context context ;
                        // 処理

                        {// コンテキスト#3 ネストできる。
                                // ここで、新たなコンテキストが始まる。
                                std::thread_local_context context ;
                                // 処理

                        }// ここで、コンテキスト#3が終わる。すなわち、objのデストラクタが走り、objが破棄される。

                }// ここで、コンテキスト#2が終わる。すなわち、objのデストラクタが走り、objが破棄される。

        }// ここで、コンテキスト#1が終わる。すなわち、objのデストラクタが走り、objが破棄される。
}

このように、コンテキストを作ることによって、thread_localなオブジェクトのlife timeを、制御できる。

これはすばらしい提案だ。是非とも規格入りするべきである。

N3039: Constexpr functions with const reference parameters (a summary)

const T& argumentsに対して、constexpr specifierを使えるようにする提案。constな参照は、定数と言ってもいいので、これは当然だ。これが認められないと、標準ライブラリの多くが、constexpr化できない。

N3040: Various threads issues in the library (LWG 1151)

スレッドに対する、細かい文面の変更。iostreamの使用、race conditionの際に限りconstと見なされるSTLのメンバー関数のリストにat()を追加、atomic read-modify-writeの文面を変更して、分かりやすくする、標準ライブラリのイテレーターの競合についての文面の追加。

N3041: Futures and Async Cleanup

N2996とN2997は、前回、一緒に採用されたのだが、その中身が、前のドラフトを参照していて、現在のドラフトに当てはめるのに、問題がある。その問題を解決(編集さん、ごめんね)

N3042: Renaming launch::any and what asyncs really might be

launch::anyをany_asyncに改名。

N3043: Converting Lambdas to Function Pointers

lambda-captureが空なlambda expressionは、同じ引数と戻り値の型の、関数ポインタに変換できるようにする提案。すなわち、

void (*ptr1)(int) = [](int) -> void {} ;
int (*ptr2)(void) = [](void) -> int { return 0 ; } ;

このようなコードが書ける。これにより、既存の関数ポインタを引数に取るコードが再利用できる。もっとも、一番ふさわしいのは、テンプレートや、std::functionを使うことなのだが。

N3044: Defining Move Special Member Functions

デフォルトのコピーコンストラクタとムーブコンストラクタを生成するための、ドラフトの文面の変更。変更する箇所が、甚だしく多い。

N3045: Updates to C++ Memory Model Based on Formalization

メモリモデルとアトミックに関する、細かな文面の変更。

N3046: Iterators in C++0x

C++のイテレーターは、素晴らしく成功したと言える。がしかし、設計に多少の問題があるのも事実だ。本来ならば、コンセプトが、その穴を埋めてくれたはずなのだが、残念ながら、コンセプトの却下により、今までのイテレーターの改良案は、すべて水泡に帰してしまった。そこで、コンセプトの研究を踏まえつつ、現状の規格の範囲で、イテレーターを改良しようという提案。

Please, I beg you C++ Working Group members. Write your goddamn papers in the plain HTML! I don't want to take any shit from crappy PDFs! Please...

No comments: