C++11では、範囲for文を拡張することを目的として、std::begin()
、std::end()
という非メンバ関数が導入されました。
std::vector<T> v;
// 先頭要素を指すイテレータ、終端イテレータを非メンバ関数で取り出す
decltype(v)::iterator first = std::begin(v);
decltype(v)::iterator last = std::end(v);
これらの非メンバ関数は組み込み配列版に対するオーバーロードが用意されていることもあり、範囲for文を拡張する以外の目的でも便利に使われはじめ、C++14では範囲for文とは直接関係のないconst_iterator版のstd::cbegin()
とstd::cend()
、reverse_iterator版のstd::rbegin()
とstd::rend()
などが導入されました。
C++1zでは、組み込み配列とコンテナを共通インタフェースで扱えることなどを目的として、以下の非メンバ関数が導入されます:
std::empty()
: コンテナが空か判定するstd::size()
: コンテナの要素数を取得するstd::data()
: コンテナの生データ(ポインタ)を取得する
これらのうち、std::size()
はとくに組み込み配列の要素数を取得するために、便利に使えるでしょう。
#include <iterator> #include <cstddef> int main() { int ar[] = {3, 1, 4}; constexpr std::size_t size = std::size(ar); static_assert(size == 3); }
この関数を使えば、#define ARRAYSIZE(a) (sizeof(a)/sizeof(*(a)))
のようなマクロは必要なくなります。
その他の要点は、以下の通りです:
- これらの関数は、
<iterator>
ヘッダで定義される - これらの関数は、constexpr関数として定義される
- これらの関数のうちコンテナ版は、戻り値の型がコンテナの定義に依存する
- たとえば、
std::empty(c)
は直接bool
型を返すよう定義されているのではなく、c.empty()
の戻り値の型を返すように定義される
- たとえば、
- これらの関数は、関数テンプレートのコンテナ版、
std::initializer_list
版、組み込み配列版のオーバーロードが標準ライブラリで定義される - これらの関数のうち
std::data()
だけは、const
左辺値参照版と非const
左辺値参照版のオーバーロードが定義される。それ以外はconst
左辺値参照版のみで、右辺値参照版はない。
宣言
// <iterator> namespace std { // 24.8, container access: template <class C> constexpr auto size(const C& c) -> decltype(c.size()); template <class T, size_t N> constexpr size_t size(const T (&array)[N]) noexcept; template <class C> constexpr auto empty(const C& c) -> decltype(c.empty()); template <class T, size_t N> constexpr bool empty(const T (&array)[N]) noexcept; template <class E> constexpr bool empty(initializer_list<E> il) noexcept; template <class C> constexpr auto data(C& c) -> decltype(c.data()); template <class C> constexpr auto data(const C& c) -> decltype(c.data()); template <class T, size_t N> constexpr T* data(T (&array)[N]) noexcept; template <class E> constexpr const E* data(initializer_list<E> il) noexcept; }
参照
- N4017 Non-member
size()
and more - N4155 Non-member
size()
and more (Revision 1) - N4280 Non-member
size()
and more (Revision 2)
お断り
この記事の内容は、C++1zが正式リリースされる際には変更される可能性があります。正式リリース後には、C++日本語リファレンスサイトcpprefjpの以下の階層の下に解説ページを用意する予定です。