2008-10-09

互換機能

C++の規格には、Compatibility featuresという項目がある。これは、歴史的な理由などで、互換性のために残されている機能のことだ。試みにC++03の互換機能を挙げてみると、

bool型に対するインクリメント演算子の使用(使うべきではない)
namespaceスコープ内でのオブジェクトの宣言にstaticキーワードを使用すること。(無名namespaceを使うべき)
Access declarations(11.3)の使用(using-declarationsを使うべき)
文字列リテラルの非constへの暗黙の変換(使うべきではない)
標準Cライブラリヘッダ、stdio.hなど(cstdioなどのヘッダを使うべき)
昔の iostream のメンバ、多すぎるので列挙しない(使うべきではない)
char * ストリーム、strstreamなど(使うべきではない)

staticキーワードとaccess declarationsと文字列リテラルに関しては、サンプルコードを示したほうがわかりやすいかもしれない。

// 別の翻訳単位から参照されたくない名前空間内の変数
namespace hito
{
    // これは互換機能、使うべきではない
    static int x ;
    // こうすべき
    namespace { int y ; }
}

class base
{
public :
    int x ;
    int y ;
} ;

class derived : private base
{
public :
    // base::xのみpublicでアクセス可能に
    base::x ; // これは互換機能、使うべきではない
    using base::x ; // こうすべき
} ;

int main()
{
    derived d ;
    d.x = 0 ; // OK
    d.y = 0 ; // Error
}

int main()
{
    // こうすべき
    char const * char_const_ptr = "Would you like to give up being a mason?" ;
    
    // 互換機能、使うべきではない。
    char * char_non_const_ptr = "No? That's wrong! Wrong! Wrong! Wrong! No! No! No! Bad! Bad!" ;
}

C++0xでは、この互換機能が増える。

まずは、binder。これはbind1stやbind2ndなどといったfunctionalヘッダで定義されている関数とクラスである。知らなくても別に恥ではない。誰もこんな糞なライブラリなど使っていないからだ。変わりに、新しく導入されたbindを使うべきだ。これはBoostのbindとよく似ていて、使い方も同じだ。

次に、auto_ptr。これは中途半端な仕様なので使うべきではない。もっと意味がはっきりとした、unique_ptrとsmart_ptrを使うべきだ。前者はコピーができず、後者は参照カウンタを備えている。

最後に、(これが本当に云いたかったのだが)、Iterator primitivesがある。これは、端的に言ってしまうと、iterator_traitsそのものをdeprecatedにしている。コンセプトがあれば、こんな使いづらいメタ関数は必要ない。

とはいっても、iterator_traitsを互換機能に落としてしまうのは、だいぶ英断だと思う。

No comments: