LoginSignup
5
3
お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

C++26 で使える(はずの) std::inplace_vector について

Last updated at Posted at 2024-07-09

どうやら P0843R13 inplace_vector が C++26 入りするみたいなので、紹介します。

概要

std::inplace_vector はその容量がコンパイル時に決定される、メモリ上で要素が連続するコンテナ型です。
std::vector などよりは std::array に近く、要素はオブジェクトそのものに格納されます。

template <class T, size_t N>
class inplace_vector;

基本的には sizeof(size_t) + sizeof(T) * N 程度のサイズになるようですが、特殊な場合として N == 0 の時にはクラス全体のサイズが 0 になるよう定められています。

メンバ

std::inplace_vectorstd::vector の持つメンバ関数を全て利用できますが、それに加えていくつかのメンバ関数が存在するようです。

try_emplace_back, try_push_back

template <class... Args>
constexpr pointer try_emplace_back(Args&&... args);

constexpr pointer try_push_back(const T& x);
constexpr pointer try_push_back(T&& x);

これらの関数は既存の emplace_backpush_back に対して、要素を追加できない時に例外を投げずに nullptr を返します。

#include <cassert>
#include <inplace_vector>

int main() {
  std::inplace_vector<int, 5> vec{3, 1, 4, 1};
  assert(*vec.try_push_back(5) == 5);
  assert(vec.try_push_back(9) == nullptr);
}

try_append_range

template <container-compatible-range<T> R>
constexpr ranges::borrowed_iterator_t<R> try_append_range(R&& rng);

C++23 で追加された append_rangetry_ 版です。
append_rangepush_back などと同様に void を返しますが、 try_append_range は追加できた要素の範囲 [first, last) の last を返します。

#include <algorithm>
#include <array>
#include <cassert>
#include <inplace_vector>
#include <ranges>

int main() {
  std::inplace_vector<int, 5> vec{3, 1};
  auto rng = std::views::iota(0, 5);
  auto it = vec.try_append_range(rng);
  assert(std::ranges::equal(vec, std::array{3, 1, 0, 1, 2}));
  assert(it == rng.begin() + 3);
}

unchecked_emplace_back, unchecked_push_back

template <class... Args>
constexpr reference unchecked_emplace_back(Args&&...);

constexpr reference unchecked_push_back(const T& x);
constexpr reference unchecked_push_back(T&& x);

上記の try_ 版に対し無条件に参照を返す版です。

unchecked_emplace_back(args...)*try_emplace_back(args...) と、 unchecked_push_back(arg)*try_push_back(arg) と等価です

既存実装

std::inplace_vector のようなコンテナ型は、これまでにも static_vector のような名前で使われてきました。 Boost.Container にも boost::container::static_vector が実装されています。

参照

P0843R13 inplace_vector
https://eel.is/c++draft
https://github.com/cplusplus/papers/issues/114

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3