2010-12-04

post-Batavia mailiingの簡易レビュー

ISO/IEC JTC1/SC22/WG21 - Papers 2010

最新ドラフトは、N3225になった。ドラフトに対する変更点は、N3226: Editor’s Reportに列挙されている。

今回は、名前通りの単純な変更や、単なる文面の誤りや不明確な点の修正などが多い。そのため、特に気になるペーパーだけを取り上げる。

N3189: Observers for the three handler functions

get_new_handler, get_unexpected, get_terminateを追加する提案。

N3197: Lockable Requirements for C++0x

名前通り。

N3198: Deprecating unary/binary_function (Rev 1)

これまた名前通り。当然deprecatedにするべきである。

N3201: Moving right along

重いコンダラ試練の道を~♪ 行くには行くが、下位互換性は守るのが標準化委員会のド根性。

暗黙のムーブを、どのような場合に生成すべきか。また、暗黙のムーブはどのように実装されるべきかという問題について論じている。

暗黙のムーブは、ユーザー定義のコピーやムーブ、デストラクターに加えて、コンストラクターが存在する場合も、生成を抑制されるべきではないかという話がひとつ。

もうひとつ、暗黙のムーブの実装をどのように定義すればよいか。問題となるのは、ムーブした後のオブジェクトのことだ。ライブラリ実装者としては、ムーブされた後のオブジェクトは、代入などをすれば使える状態であってほしい。

Object x ;
Object y = std::move( x ) ;
// xはムーブされた後の状態になる
Object z ;
x = z ; // xが使用可能の状態になる。

しかし、一体この状態をどうやって作り出せばいいのか。クラスの実装次第では、ムーブ後のオブジェクトに対する代入ができない可能性もある。では、ムーブ後の状態を、暗黙のムーブという一般的な実装から作り出すのは、どうすればいいのか。

デフォルトコンストラクターを使うというのはどうだろう。つまり、暗黙のムーブは、各メンバーごとにムーブした後のオブジェクトに対して、デフォルトコンストラクターを呼び出すのだ。これによって、妥当な状態にすることができる。もし、別の実装がしたければ、ユーザーは自前のムーブを実装すべきである。

しかし、勝手にデフォルトコンストラクターが呼び出されるというのは、やはり色々と問題がある。さて、どうするか。

個人的には、現行FCDのままの方が、一番混乱が少なくていいと思う。

N3202: To which extent can noexcept be deduced?

noexceptには、ひとつ問題がある。わざわざ、すべての関数にnoexceptを指定するのが、甚だ面倒だということだ。それゆえ、インライン関数は、noexceptを暗黙のうちに推定してもいいのではないだろうか。つまり、インライン関数の関数本体に、例外を投げるかもしれない式が含まれていない場合、そのインライン関数は、noexcept(true)と暗黙のうちに指定されるべきではないか。という提案。

N3203: Tightening the conditions for generating implicit moves

ユーザー定義のコピー、ムーブ、デストラクターがある場合、暗黙のムーブを生成しない。ユーザー定義のコピー、ムーブ、デストラクターがある場合、暗黙のコピーを生成する機能を、deprecatedにする。

ユーザー定義のコピーがあるのに暗黙のコピーを生成する場合というのは、すこし妙に聞こえるかもしれない。これは、ユーザー定義のコピー代入演算子があって、コピーコンストラクターが定義されていない場合、またはその逆である。

struct X
{
    // ユーザー定義のコピー代入演算子
    X & operator = ( X const & ) { return *this ; }

    // 暗黙のコピーコンストラクターが生成される
} ;

このような挙動は、C++0xではdeprecatedであるので、まともなC++プログラマーならば、この挙動に頼ったコードを書いてはいけない。

N3204: Deducing "noexcept" for destructors

デストラクターに明示的にnoexceptが指定されていない場合、暗黙のデストラクターと同じ方法でnoexceptが推定される。結果的に、明示的にnoexcept(false)を指定しない限り、デストラクターはnoexcept(true)となる。

n3205 Delete operators default to noexcept

名前通り。

N3206: Override control: Eliminating Attributes

いままでattributeの機能であった、base_check, final, override, hidingを、contextual keywordにする。base_checkはexplicitに、hidingはnewになる。

struct Base
{
    int x ;
    virtual void f() ;
} ;

struct Derived explicit final : Base
{
    int x new ;
    void f() override ;
} ;

finalとoverrideは、contextual keywordなので、識別子としても利用出来る。

ただし、会議後、この文法にも新たな問題が見つかっており、おそらく、また文法は変わるだろうと思われる。ひょっとすると、hidingがなくなってしまうかもしれない。

N3207: noexcept(auto)

関数の本体から、noexceptを推定させるための例外指定を追加する提案。以下のようになる。

void f() {} // 例外を投げるかもしれない関数
void g() noexcept { } // 例外を投げないと保証されている関数

// noexcept(false)
void h() noexcept(auto)
{
    f() ; // 例外を投げる可能性のある式
}

// noexcept(true)
void i() noexcept(auto)
{
    g() ; // 例外を投げる可能性のない式
} 

N3209: Progress guarantees for C++0x (revised)

残念ながら、私はこのペーパーの内容を理解していない。スレッド間の保証は難しい。

N3210: New wording for arithmetic on ratios

文面の書き換え

N3214: US 19: Ambiguous use of "use" (version 2)

ODRのuseと、一般動詞としてのuseが混用されていてややこしいというNBコメントに対し、ODRに関するuseを、odr-useに置き換える変更。

N3216: Removing Implicit Move Constructors and Move Assignment Operators

今回のドラフトでは採用されなかったが、もし、暗黙のムーブを取り除くとした場合の、規格の文面の変更案。

N3217: Wording for brace-initializers as default arguments

{}をデフォルト実引数として使えるようにするための文面。

N3218: Core Issue 1125: Unclear definition of "potential constant expression" (DE 8, GB 26)

定数式の文面の不明確な点を解消。

1 comment:

Patmos Pete said...

あなたに神を愛しています。聖書を読んでください。