C++14標準ライブラリから配列版のstd::begin
/end
非メンバ関数がconstexpr指定され、constexpr指定付きのstd::cbegin
/cend
非メンバ関数が追加された。また、std::initializer_list<E>
のconstexpr対応に伴い、同オーバーロードstd::begin
/end
非メンバ関数もconstexpr指定される*1。
// <iterator>標準ヘッダ template <class C> auto begin(C& c) -> decltype(c.begin()); template <class C> auto begin(const C& c) -> decltype(c.begin()); template<class T, size_t N> constexpr T* begin(T (&array)[N]); // C++14以降 template<class C> constexpr auto cbegin(const C& c) -> decltype(std::begin(c)); // C++14以降 // <initializer_list>標準ヘッダ template<class E> constexpr const E* begin(initializer_list<E> il); // C++14以降
これらにより、C++14以降はレガシーC配列と初期化子リストに限ってconstexpr関数内でもbegin
/end
, cbegin
/cend
非メンバ関数を使用できる。C++14標準コンテナクラスはconstexpr未対応*2。constexpr対応が必要ならSproutライブラリなどを検討のこと。
- 2016-03-28追記:C++17(C++1z)では
std::array
コンテナのconstexpr対応が行われ、レガシーC配列と同様に扱えるようになる(→id:yohhoy:20160328)
// C++14以降 #include <iterator> #include <initializer_list> // コンテナ版(実質はレガシーC配列用) template<class C> constexpr int sum(const C& c) { int acc = 0; for (auto i = std::cbegin(c), e = std::cend(c); i != e; ++i) acc += *i; // または for (auto e : c) { acc += e; } もOK return acc; } // 初期化子リスト版 constexpr int sum(std::initializer_list<int> il) { int acc = 0; for (auto i = std::cbegin(il), e = std::cend(il); i != e; ++i) acc += *i; // または for (auto e : il) { acc += e; } もOK return acc; } constexpr int a[] = { 1, 2, 3 }; static_assert(sum(a) == 6, ""); static_assert(sum({1, 2, 3}) == 6, "");
関連URL