yohhoyの日記

技術的メモをしていきたい日記

std::arrayの(ほぼ)constexprネイティブ対応

C++1z(C++17)標準ライブラリのシーケンスコンテナstd::array<T,N>では、ほぼ全てのメンバ関数*1がconstexpr指定される。あわせて、関連するイテレータ型やbegin/end関数群*2へもconstexpr指定が追加される。

2019-09-11追記:C++2a(C++20)に向けて (PDF)P1023R0P1032R1 が採択され、全ての操作がconstexpr対応した。

下記例示は記事 std::begin/endとconstexpr指定 からの引用コードをベースに追記したもの。

#include <array>

// std::arrayとレガシーC配列に対応
template<typename 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; }
  return acc;
}

constexpr int a[] = { 1, 2, 3 };
static_assert(sum(a) == 6, "");  // C++14以降

std::array<int, 3> arr = { 1, 2, 3 };
static_assert(sum(arr) == 6, "");  // C++17(C++1z)以降

関連URL

*1:変更操作 array::fill, array::swap メンバ関数はconstexpr指定無しのまま。また比較演算子オーバーロードなどの非メンバ関数もconstexpr指定の対象外。なお、std::get<N> 非メンバ関数C++14以降でconstexpr指定されている。

*2:ここでは begin/end, cbegin/cend, rbegin/rend, crbegin/crend メンバ関数および非メンバ関数を総称した。