この記事のポイント

  • std::optional導入のレビュー観点を体系整理
  • ヌル許容設計をレビューアーがどう読み解き整理するかの実務技術を習得
  • API契約粒度の責務整理をレビューで提案可能にする

そもそもstd::optionalとは何か

C++17で導入されたstd::optional<T>「値の有無を型システムに乗せて表現する設計技術」である。

従来 optional利用
T* optional
nullptr std::nullopt
存在保証曖昧 型で保証強化

レビューアーは「この戻り値はoptionalで設計すべき責務か?」を設計脈絡から読み解く力が必須になる。

なぜこれをレビューするのか

  • nullptr許容設計が曖昧文化化する現場が多い
  • 呼出側が存在確認漏洩事故を頻発させる
  • 契約として「存在可能性あり」設計を型レベルで宣言できる武器になる
  • レビュー段階で契約粒度整理を支援可能になる

レビューアー視点

  • この関数は「値無し」を合法パスとして契約宣言しているか?
  • 契約違反 vs 不在許容を整理できているか?
  • 利用者が存在確認責務を持つ前提設計か?
  • null許容ではなくoptional型で契約宣言されているか?
  • 契約ドキュメントに粒度整理されているか?

開発者視点

  • optionalは契約型:存在可能性設計宣言ツール
  • null許容は極力排除(ポインタ利用は保持契約責務のみ)
  • 例外設計と並列活用し役割分離
  • 内部表現null許容でも公開APIはoptional統一

良い実装例

例1:検索APIのoptional化

検索API設計
std::optional<User> findUser(int userId) {
    if (auto u = db.query(userId)) {
        return u;
    }
    return std::nullopt;
}
  • 存在可能性 → optional型契約

例2:パーサーAPIのoptional化

パースAPI設計
std::optional<Date> parseDate(const std::string& str) {
    if (validFormat(str)) {
        return Date::from(str);
    }
    return std::nullopt;
}
  • 失敗 → nullopt収束

レビュー観点

  • 契約違反ではなく合法パスであると設計明文化されているか
  • ポインタnull許容とoptionalが混在排除されているか
  • 利用者側責務で存在確認が明文化されているか
  • 統一的な戻り値粒度が維持されているか
  • std::nulloptによる初期化統一が実施されているか

良くない実装例: ケース1(nullableポインタ混入)

nullableポインタ型
User* findUser(int userId);
@Reviewer
ポインタnull許容は設計契約が曖昧になります。optional<T>型に統一してください。

改善例

改善例(optional型統一)
std::optional<User> findUser(int userId);

良くない実装例: ケース2(戻り値不統一)

API粒度崩壊
std::optional<User> find();
bool exists();
@Reviewer
同一責務API内で戻り粒度が崩壊しています。契約統一してください。

改善例

改善例(粒度統一)
std::optional<User> find();

良くない実装例: ケース3(契約粒度混乱)

不在通知混在
User findOrThrow(int userId);
@Reviewer
optional統一文化に対し例外分離が混在しています。契約統一指針を決定してください。

改善例

改善例(契約文化整理)
std::optional<User> find();

PlantUML:optional責務整理図

UML Diagram

optional適用優先パターン一覧

適用領域 代表API
検索API findById, getByKey
パースAPI parseDate, parseConfig
設定読込 getOptionalParam
条件分岐 filterOptional

レビューアーは「ここはoptional型に統一できます」提案を常時提供できることが重要。

ロギング統合例

optional存在確認
auto userOpt = repository.findUser(userId);
if (!userOpt) {
    logger.warn("User not found: id={}", userId);
    monitoring.notify("USER_NOT_FOUND");
}
  • 不在判定と通知を統一整理

契約責務レビュー支援質問集

質問例 意図
この戻り値は設計的に存在可能性がありますか? optional適用可否確認
null許容とoptionalが混在していませんか? 契約型統一確認
呼び出し側はhas_value確認責務を負っていますか? 利用者責務確認
契約粒度がAPI群内で統一されていますか? 統一文化確認

レビューアーは契約設計可視化レビュー文化を現場に定着させる役割を持つ。

観点チェックリスト

まとめ

レビューアーがoptionalレビューで常に問うべきは
「この値の有無は契約上許容なのか、それとも契約違反なのか?」
です。

  • optional → 契約責務型表現文化
  • nullable → 契約曖昧排除文化
  • 利用者責務 → has_value統一文化
  • 統一契約文化 → 設計粒度整理文化

レビュー現場では
「存在可能性を契約型に収束させるレビュー文化」
が現場品質と設計統一性を大幅に向上させます。