最終更新日時:
が更新

履歴 編集

function
<type_traits>

std::is_within_lifetime(C++26)

namespace std {
  template<class U=void, class T>
  consteval bool is_within_lifetime(const T* p) noexcept; // (1) C++26
}

概要

定数式において、pに配置されているオブジェクトが有効期間内にあり、かつconst U*のポインタへキャスト可能かどうかを判定する。

共用体のアクティブメンバ判定

この関数は主に、共用体の指定されたメンバがアクティブかを定数式中で判定するためのものである。定数式では非アクティブな共用体メンバへのアクセスができないため、以下のような非アクティブなメンバの値を使用してアクティブメンバを判定する方法が使用できない。

struct OptBool {
  union { bool b; char c; };

  OptBool() : c(2) { }
  OptBool(bool b) : b(b) { }

  auto has_value() const -> bool {
    return c != 2;
  }

  auto operator*() -> bool& {
    return b;
  }
};

この関数を使用することで、コンパイル時に指定メンバがアクティブかを判定することができる。

ダウンキャスト可能かどうかの判定

第一テンプレートパラメータUTのポインタをUのポインタへキャスト可能かどうかを判定するためのもので、主にTからUへのダウンキャストが定数式中で可能かどうかを判定するために使用する。

struct Base {};
struct Derived : public Base {};

consteval void f() {
  Base b{};
  Derived d{};
  Base* d_ptr = &d;

  // d_ptrはDerivedのポインタにダウンキャスト可能
  assert(std::is_within_lifetime<Derived>(d_ptr));
  // &bはDerivedにダウンキャスト不可
  assert(std::is_within_lifetime<Derived>(&b) == false);
}

適格要件

static_cast<const volatile U*>(p)適格であること。

戻り値

pが有効期間内にあるオブジェクトへのポインタかつstatic_cast<const volatile U*>(p)が定数部分式であればtrue、そうでなければfalseを返す。

備考

  • Eを定数式として評価する際、pが定数式で使用可能なオブジェクトを指しているか、そのオブジェクトの完全な有効期間がE内で始まっていない限り、この関数の呼び出しは不適格となる

#include <type_traits>

struct OptBool {
  union { bool b; char c; };

  constexpr OptBool() : c(2) { }
  constexpr OptBool(bool b) : b(b) { }

  constexpr auto has_value() const -> bool {
    if consteval {
      return std::is_within_lifetime(&b);   // 定数式評価中は、cを読み取ることはできない
    } else {
      return c != 2;                        // 実行時評価中は、cを読み取らないといけない
    }
  }

  constexpr auto operator*() const -> const bool& {
    return b;
  }
};

int main() {
  constexpr OptBool disengaged;
  constexpr OptBool engaged(true);
  static_assert(!disengaged.has_value());
  static_assert(engaged.has_value());
  static_assert(*engaged);
}

出力

バージョン

言語

  • C++26

処理系

参照