2014-01-17

C++03とC++11の違い:アルゴリズム編

今回は、C++03からC++11にかけて変わった互換性の問題を引き起こすおそれのある、今やおなじみになったシリーズの、アルゴリズム編だ。

変更:一部のアルゴリズムの、入力の結果の挙動が、ある未規定な状態から、別の未規定の状態に変わる。

これは、C++11にムーブが導入されたためだ。std::removeやstd::remove_ifなどが該当する。

// C++03とC++11で挙動が変わる例
#include <vector>
#include <algorithm>

template < typename T >
void f( T const & t1, T const & t2, T const & t3 )
{
    // t1, t2, t3はそれぞれ等しくないオブジェクトであるとする

    std::vector<> v ;
    v.push_back( t1 ) ;
    v.push_back( t2 ) ;
    v.push_back( t3 ) ;

    // vectorの要素 { t1, t2, t3 } 

    std::remove( v.begin(), v.end(), t2 ) ;

    // vectorの要素 { t1, t3, 未規定の状態 }
}

C++03でも、C++11でも、このコードを実行した後のv[2]の状態は、未規定である。ただし、C++03では、コピーされるのに対し、C++11では、ムーブされる。そのために、未規定は未規定でも、異なる状態の未規定になる。

これは、元々が未規定の状態になるという点においては変わらないので、それほど問題になることはないだろう。C++11規格では、標準ライブラリに渡すユーザー定義型のムーブ後の状態は、未規定だが、規格の型に対する要求(たとえば、DefaultConstructibleを満たすとか)は、依然として満たしていなければならないと規定している。これはユーザーの責任でもある。

次回は数値ライブラリについて。

1 comment:

Unknown said...

最後の行のコメントですが、v[1] の内容は t2 ではなく t3 ではないでしょうか?