yohhoyの日記

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

制約式std::bool_constant<cond>::value

C++20 制約式(constraint-expression)でテンプレートパラメータに依存する定数条件式condを表現する場合、非定数式に起因するハードエラーを防ぐためstd::bool_constant<cond>::valueと記述する必要がある。

#include <type_traits>

struct X {
  // X::valueは非定数式
  static inline int value = 42;
};
struct Y {
  // Y::valueは定数式
  static constexpr inline int value = 42;
};
struct Z {};

template<typename T>
concept C0 = (T::value == 42);
static_assert(!C0<X>);  // NG: ill-formed
static_assert( C0<Y>);  // OK
static_assert(!C0<Z>);  // OK

template<typename T>
concept C1 = std::bool_constant<T::value == 42>::value;
static_assert(!C1<X>);  // OK
static_assert( C1<Y>);  // OK
static_assert(!C1<Z>);  // OK

C++標準ライブラリではuniform_random_bit_generatorコンセプトで同テクニックが利用される。C++20 26.6.2.3/p1より引用。

A uniform random bit generator g of type G is a function object returning unsigned integer values such that each value in the range of possible results has (ideally) equal probability of being returned. [Note: The degree to which g's results approximate the ideal is often determined statistically. --end note]

template<class G>
  concept uniform_random_bit_generator =
    invocable<G&> && unsigned_integral<invoke_result_t<G&>> &&
    requires {
      { G::min() } -> same_as<invoke_result_t<G&>>;
      { G::max() } -> same_as<invoke_result_t<G&>>;
      requires bool_constant<(G::min() < G::max())>::value;
    };

関連URL