Review TODO — Fixed Capacity Vector post

Review of fixed-capacity-vector.md against fixed_capacity_vector.hpp (done 2026-06-14). Line numbers refer to fixed-capacity-vector.md unless noted.

Verdict

Close to publishable. One real factual error (std::start_lifetime_as), three content TODO items still open, one garbled sentence, and a frontmatter/date mismatch from the file move.

Open content sections (the original TODO list, remaining items)

  • emplace_back() — only named at L267, never shown. Add the variadic perfect-forwarding implementation (Args&&... + std::forward); that’s the teaching point.
  • Assignment operators — section is still skeletal (L212–223, “we do not list the full code here”). Show the destroy-then-reconstruct pattern, and be honest that it is not strongly exception-safe (a throwing copy leaves the vector partially populated) — that tradeoff is the interesting part.
  • resize() — not covered at all. Note that it’s implemented via emplace_back() with no args (hpp L307), so it silently requires T to be default-constructible — one sentence, and a good reason to introduce emplace_back first.

Already done from the original list: friend declaration, requires constraints, constexpr/reinterpret_cast, initializer_list ctor, STL compatibility section.

Technical correctness

  • Rewrite the std::start_lifetime_as paragraph (L101). Three problems:
    • It’s C++23 (P2590R2, 2022), not C++26.
    • “Not implemented in any major compiler” is stale — as of mid-2026 both libstdc++ (GCC, Aug 2025) and MSVC (Build Tools 14.51) ship it; libc++ lags.
    • It would not actually enable constexpr: start_lifetime_as is not a constexpr function. Its purpose is to make the runtime reinterpretation of raw storage well-defined (a lifetime issue), not to unlock constexpr. The real constexpr blocker is the untyped std::byte buffer itself; std::inplace_vector (C++26) gets constexpr by using union-based storage. Reframe accordingly (and it ties nicely into the inplace_vector mention at L360).
    • Sources: cppreference (cpp/memory/start_lifetime_as); P2590R2 (open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2590r2.pdf); GCC libstdc++ patch (gcc.gnu.org/pipermail/gcc-patches/2025-August/693665.html).

Prose / typos

  • L223 — garbled, two duplications: “good practice regardless to guarantee the correct address regardless” and “circumvent any problems any problems with applying &”. Rewrite the whole sentence.
  • L227 — “shift our focus toward implement operations” → “implementing”
  • L231 — “call the data() function return a pointer” → “returning”
  • L86 — “instruct the clang-tidy linter from recommending us to use” → “stop the clang-tidy linter from recommending” / “instruct … not to recommend”
  • L76 — “generate a code to initialize” → “generate code”
  • L28 — “Limiting noexcept w.r.t. to the value type” → “w.r.t. the”
  • L40 — “deletion arbitrary position” → “deletion at an arbitrary position”

Frontmatter / metadata

  • Date vs. directory mismatchdate: '2026-01-12' (L2) but the file is now in content/posts/2026/06/ (old 2026/01/… was deleted). Bump the date to the real June publish date or it sorts under January.
  • draft: true (L4) — flip to false when publishing.
  • L27 malformed URL…/new.html#Placement_new#Rule_of_five has two # fragments. Drop the stray #Rule_of_five.
  • Mixed http:// vs https:// for cppreference (L106, L231, L305 use http://; rest https://). Harmless but inconsistent.

Optional — code-level notes in fixed_capacity_vector.hpp (not blog-blocking)

  • Same-capacity move ctor (hpp L137) isn’t exception-safe. Sets m_size(other.m_size) before the loop; if T’s move ctor throws mid-loop, the destructor runs std::destroy over unconstructed slots → UB. The cross-capacity version (L167) does it correctly (increment inside the loop).
  • Cross-capacity move-assign noexcept (hpp L275) tests is_nothrow_move_assignable_v, but the body does placement-new + destroy_at (move-construction); should test is_nothrow_move_constructible_v.
  • Inconsistent constexpr on iteratorsbegin/end/cbegin/cend aren’t constexpr, but rbegin/rend/crbegin/crend are, even though none can be evaluated at compile time (all go through the non-constexpr data()).