C++03規格時点で存在したアルゴリズム関連ライブラリに対するC++11規格での変更点をまとめています。
概要 †
当文書では、主にコンテナに対して適用可能なアルゴリズムを提供する <algorithm> と、アルゴリズムに関連する機能を提供する <functional> および <iterator> について、C++11規格での変更点をまとめている。
多くのアルゴリズムはアルゴリズム適用範囲を表す2つのイテレータを引数として受け取る。
1つ目のイテレータは適用範囲の開始位置を、2つ目のイテレータは終端位置をそれぞれ指す(終端位置自体は適用範囲に含まれない)。
当文書中では、この2引数をまとめてコンテナ範囲と呼ぶ。
アルゴリズムの中には関数オブジェクトを引数にとるものがあり、それらにはC++11規格の言語機能であるラムダ式によって作成された関数オブジェクトを渡すことも可能である。
例えば、 int
型の値を保持するコンテナクラス型(あるいは固定長配列型)のインスタンス nums
の中から値が 0
以上 100
未満の要素を検索するコードは下記のように書くことができる。
| auto itr = find_if(begin(nums), end(nums), [](int n){ return (n >= 0 && n < 100); });
if (itr != end(nums)) { }
|
<algorithm> †
文中の「x
を満たす」とは、 if (x)
にヒットする(即ち (x) != false
である)ことを表す。
下記の関数が定義された。
| template<class InputIterator, class UnaryPredicate>
bool all_of(InputIterator first, InputIterator last, UnaryPredicate pred);
|
| template<class InputIterator, class UnaryPredicate>
bool any_of(InputIterator first, InputIterator last, UnaryPredicate pred);
|
| template<class InputIterator, class UnaryPredicate>
bool none_of(InputIterator first, InputIterator last, UnaryPredicate pred);
|
| template<class InputIterator, class UnaryPredicate>
InputIterator find_if_not(InputIterator first, InputIterator last, UnaryPredicate pred);
|
| template<class InputIterator1, class InputIterator2>
bool is_permutation(InputIterator1 first1, InputIterator1 last1, InputIterator2 first2);
template<class InputIterator1, class InputIterator2, class BinaryPredicate>
bool is_permutation(
InputIterator1 first1,
InputIterator1 last1,
InputIterator2 first2,
BinaryPredicate pred);
|
| template<class InputIterator, class Size, class OutputIterator>
OutputIterator copy_n(InputIterator first, Size num, OutputIterator result);
|
| template<class InputIterator, class OutputIterator, class UnaryPredicate>
OutputIterator copy_if(
InputIterator first,
InputIterator last,
OutputIterator result,
UnaryPredicate pred);
|
| template<class InputIterator, class OutputIterator>
OutputIterator move(InputIterator first, InputIterator last, OutputIterator result);
|
| template<class BidirectionalIterator1, class BidirectionalIterator2>
BidirectionalIterator2 move_backward(
BidirectionalIterator1 first,
BidirectionalIterator1 last,
BidirectionalIterator2 result);
|
| template<class RandomAccessIterator, class URNG>
void shuffle(RandomAccessIterator first, RandomAccessIterator last, URNG&& urng);
|
| template<class InputIterator, class UnaryPredicate>
bool is_partitioned(InputIterator first, InputIterator last, UnaryPredicate pred);
|
| template<
class InputIterator,
class OutputIterator1,
class OutputIterator2,
class UnaryPredicate>
pair<OutputIterator1, OutputIterator2> partition_copy(
InputIterator first,
InputIterator last,
OutputIterator1 result_true,
OutputIterator2 result_false,
UnaryPredicate pred);
|
| template<class ForwardIterator, class UnaryPredicate>
ForwardIterator partition_point(
ForwardIterator first,
ForwardIterator last,
UnaryPredicate pred);
|
| template<class ForwardIterator>
bool is_sorted(ForwardIterator first, ForwardIterator last);
template<class ForwardIterator, class Compare>
bool is_sorted(ForwardIterator first, ForwardIterator last, Compare comp);
|
| template<class ForwardIterator>
ForwardIterator is_sorted_until(ForwardIterator first, ForwardIterator last);
template<class ForwardIterator, class Compare>
ForwardIterator is_sorted_until(
ForwardIterator first,
ForwardIterator last,
Compare comp);
|
| template<class RandomAccessIterator>
bool is_heap(RandomAccessIterator first, RandomAccessIterator last);
template<class RandomAccessIterator, class Compare>
bool is_heap(RandomAccessIterator first, RandomAccessIterator last, Compare comp);
|
| template<class RandomAccessIterator>
RandomAccessIterator is_heap_until(
RandomAccessIterator first,
RandomAccessIterator last);
template<class RandomAccessIterator, class Compare>
RandomAccessIterator is_heap_until(
RandomAccessIterator first,
RandomAccessIterator last,
Compare comp);
|
| template<class T>
pair<const T&, const T&> minmax(const T& a, const T& b);
template<class T, class Compare>
pair<const T&, const T&> minmax(const T& a, const T& b, Compare comp);
template<class T>
pair<T, T> minmax(initializer_list<T> values);
template<class T, class Compare>
pair<T, T> minmax(initializer_list<T> values, Compare comp);
|
| template<class ForwardIterator>
pair<ForwardIterator, ForwardIterator> minmax_element(
ForwardIterator first,
ForwardIterator last);
template<class ForwardIterator, class Compare>
pair<ForwardIterator, ForwardIterator> minmax_element(
ForwardIterator first,
ForwardIterator last,
Compare comp);
|
下記の関数オーバロードが定義された。
| template<class T> T min(initializer_list<T> values);
template<class T, class Compare> T min(initializer_list<T> values, Compare comp);
template<class T> T max(initializer_list<T> values);
template<class T, class Compare> T max(initializer_list<T> values, Compare comp);
|
関数 swap
が <utility> に移動した。
ただし既存の多くの処理系ではC++03規格以前のコードを利用できるように #include <algorithm>
のみでも利用可能になっていると思われる。
関数 find_first_of
の定義が変更され、検索対象となるコンテナ範囲(第1引数および第2引数)のイテレータ要件が ForwardIterator
から InputIterator
になった。
検索要素となるコンテナ範囲(第3引数および第4引数)のイテレータ要件は ForwardIterator
のままである。
関数 fill_n
および generate_n
の定義が変更され、値設定範囲の終端を指すイテレータを戻り値として返すようになった。
関数 rotate
の定義が変更され、元の先頭要素の移動先を指すイテレータを戻り値として返すようになった。
関数 random_shuffle
の定義が一部変更された。
| template<class RandomAccessIterator, class RandomNumberGenerator>
void random_shuffle(
RandomAccessIterator first,
RandomAccessIterator last,
RandomNumberGenerator& gen);
|
| template<class RandomAccessIterator, class RandomNumberGenerator>
void random_shuffle(
RandomAccessIterator first,
RandomAccessIterator last,
RandomNumberGenerator&& gen);
|
関数 partition
の定義が変更され、コンテナ範囲と戻り値のイテレータ要件が BidirectionalIterator
から ForwardIterator
になった。
<functional> †
文中で型名が unspecified
となっているものは処理系依存の型であることを表す。
関数の戻り値等として変数に受け取りたい場合は下記のように auto
を用いる。
| auto less_than_zero = bind(less<int>(), std::placeholders::_1, 0);
|
名前空間 std::placeholders
が定義された。
関数 bind
の引数として用いるプレースホルダのインスタンスが定義されている。
| namespace std
{
namespace placeholders
{
extern unspecified _1;
extern unspecified _2;
extern unspecified _3;
}
}
|
下記のクラステンプレートが定義された。
| template<class T> struct bit_and; template<class T> struct bit_or; template<class T> struct bit_xor;
|
| template<class T> function; template<class Ret, class ...Args> class function<Ret (Args...)>;
|
| template<class T> struct hash; template<> struct hash<bool>;
template<> struct hash<char>;
template<> struct hash<signed char>;
template<> struct hash<unsigned char>;
template<> struct hash<char16_t>;
template<> struct hash<char32_t>;
template<> struct hash<wchar_t>;
template<> struct hash<short>;
template<> struct hash<unsigned short>;
template<> struct hash<int>;
template<> struct hash<unsigned int>;
template<> struct hash<long>;
template<> struct hash<unsigned long>;
template<> struct hash<long long>;
template<> struct hash<unsigned long long>;
template<> struct hash<float>;
template<> struct hash<double>;
template<> struct hash<long double>;
template<class T> struct hash<T*>;
|
| template<class T> struct is_bind_expression;
|
| template<class T> struct is_placeholder;
|
| template<class T> class reference_wrapper;
|
exception
クラスを継承した bad_function_call
クラスが定義された。
下記の関数が定義された。
| template<class Func, class ...Args>
unspecified bind(Func&& func, Args&&... args);
template<class Ret, class Func, class ...Args>
unspecified bind(Func&& func, Args&&... args);
|
| template<class Ret, class T>
unspecified mem_fn(Ret T::* mfunc);
|
| template<class T>
reference_wrapper<T> ref(T& value) noexcept;
template<class T>
reference_wrapper<T> ref(reference_wrapper<T>& value) noexcept;
template<class T> void ref(const T&&) = delete;
|
| template<class T>
reference_wrapper<const T> cref(const T& value) noexcept;
template<class T>
reference_wrapper<const T> cref(reference_wrapper<const T>& value) noexcept;
template<class T> void cref(const T&&) = delete;
|
下記の定義が非推奨となった。
unary_function
binary_function
binder1st
binder2nd
bind1st
bind2nd
pointer_to_unary_function
pointer_to_binary_function
ptr_fun
mem_fun_t
mem_fun1_t
const_mem_fun_t
const_mem_fun1_t
mem_fun
mem_fun_ref_t
mem_fun1_ref_t
const_mem_fun_ref_t
const_mem_fun1_ref_t
mem_fun_ref
unary_function
や binary_function
を継承して実装されていた関数オブジェクトクラス(unary_negate
や less
等)が、それらを継承せずに実装されるようになった。
処理内容に変更はない。
<iterator> †
文中で型名が unspecified
となっているものは処理系依存の型であることを表す。
すべてのイテレータの要件に、関数 swap
による値の交換が可能であることが定められた。
下記のクラステンプレートが定義された。
| template<class Iterator>
class move_iterator;
|
下記の関数が定義された。
| template<class Container>
auto begin(Container& c) -> decltype(c.begin());
template<class Container>
auto begin(const Container& c) -> decltype(c.begin());
template<class T, size_t N>
T* begin(T (&c)[N]);
|
| template<class Container>
auto end(Container& c) -> decltype(c.end());
template<class Container>
auto end(const Container& c) -> decltype(c.end());
template<class T, size_t N>
T* end(T (&c)[N]);
|
| template<class BidirectionalIterator>
BidirectionalIterator prev(
BidirectionalIterator itr,
typename iterator_traits<BidirectionalIterator>::difference_type count = 1);
|
| template<class ForwardIterator>
ForwardIterator next(
ForwardIterator itr,
typename iterator_traits<ForwardIterator>::difference_type count = 1);
|
| template<class Iterator>
move_iterator<Iterator> make_move_iterator(const Iterator& itr);
|
クラステンプレート reverse_iterator
のメンバ関数 operator[]
の定義が変更され、戻り値の型が reference
から処理系依存の型に変更された。
下記のクラステンプレートのコピー代入演算子の引数型が container_type::const_reference
から const container_type::value_type&
に変更された。
また、 container_type::value_type&&
を引数にとるムーブ代入演算子が定義された。
front_insert_iterator
back_insert_iterator
insert_iterator
クラステンプレート istream_iterator
のコンストラクタの定義が下記のように変更された。
- 引数なしのデフォルトコンストラクタは
value_type
がリテラル型の場合に限り constexpr
コンストラクタとなる。
- コピーコンストラクタは
default
指定される。
クラステンプレート istreambuf_iterator
のメンバ型の定義が一部変更された。
| typedef char_type* pointer;
typedef char_type& reference;
|
| typedef unspecified pointer;
typedef char_type reference;
|
関数 inserter
の定義が変更された。
| template<class Container, class Iterator>
insert_iterator<Container> inserter(Container& c, Iterator itr);
|
| template<class Container>
insert_iterator<Container> inserter(Container& c, typename Container::iterator itr);
|
クラステンプレート reverse_iterator
を引数にとる下記の関数の定義が変更された。
| template<class Iterator>
bool operator==(
const reverse_iterator<Iterator>& a,
const reverse_iterator<Iterator>& b);
template<class Iterator>
bool operator!=(
const reverse_iterator<Iterator>& a,
const reverse_iterator<Iterator>& b);
template<class Iterator>
bool operator<(
const reverse_iterator<Iterator>& a,
const reverse_iterator<Iterator>& b);
template<class Iterator>
bool operator<=(
const reverse_iterator<Iterator>& a,
const reverse_iterator<Iterator>& b);
template<class Iterator>
bool operator>(
const reverse_iterator<Iterator>& a,
const reverse_iterator<Iterator>& b);
template<class Iterator>
bool operator>=(
const reverse_iterator<Iterator>& a,
const reverse_iterator<Iterator>& b);
template<class Iterator>
typename reverse_iterator<Iterator>::difference_type operator-(
const reverse_iterator<Iterator>& a,
const reverse_iterator<Iterator>& b);
|
| template<class Iterator1, class Iterator2>
bool operator==(
const reverse_iterator<Iterator1>& a,
const reverse_iterator<Iterator2>& b);
template<class Iterator1, class Iterator2>
bool operator!=(
const reverse_iterator<Iterator1>& a,
const reverse_iterator<Iterator2>& b);
template<class Iterator1, class Iterator2>
bool operator<(
const reverse_iterator<Iterator1>& a,
const reverse_iterator<Iterator2>& b);
template<class Iterator1, class Iterator2>
bool operator<=(
const reverse_iterator<Iterator1>& a,
const reverse_iterator<Iterator2>& b);
template<class Iterator1, class Iterator2>
bool operator>(
const reverse_iterator<Iterator1>& a,
const reverse_iterator<Iterator2>& b);
template<class Iterator1, class Iterator2>
bool operator>=(
const reverse_iterator<Iterator1>& a,
const reverse_iterator<Iterator2>& b);
template<class Iterator1, class Iterator2>
auto operator-(
const reverse_iterator<Iterator1>& a,
const reverse_iterator<Iterator2>& b) -> decltype(b.base() - a.base());
|