potisanのプログラミングメモ

プログラミング素人です。昔の自分を育ててくれたネット情報に少しでも貢献できるよう、情報を貯めていこうと思っています。Windows環境のC++やC#がメインです。

C++20 std::numeric_limitsが対応する型の制約

std::numeric_limits<T>Tが対応する型(特殊化する型)ならis_specializedtrueとなるため、以下のコンセプトでstd::numeric_limits<T>が対応する型に制約できます。

#include <numeric>

template <typename T>
concept limited_number = std::numeric_limits<T>::is_specialized;

以下は使用例です。

#include <string>
#include <numeric>

template <typename T>
concept limited_number = std::numeric_limits<T>::is_specialized;

int main()
{
    auto f1 = limited_number<int>;         // true
    auto f2 = limited_number<std::string>; // false
}
#include <string>
#include <numeric>

template <typename T>
concept limited_number = std::numeric_limits<T>::is_specialized;

template <limited_number T>
void f()
{
}

int main()
{
    f<int>();
    f<std::string>(); // コンパイルエラー
}

テンプレートクラスのコンセプトにはstd::constructive_fromがありますが、std::numeric_limits<T>は対応しない型に対してもテンプレートが用意されているため、こちらは使用できません。

#include <concepts>
#include <string>
#include <numeric>

template <typename T>
concept wrong_limited_number = std::constructible_from<std::numeric_limits<T>>;

int main()
{
    auto f1 = wrong_limited_number<int>;         // true
    auto f2 = wrong_limited_number<std::string>; // true
}

なお、整数、浮動小数の制限にはそれぞれstd::integralstd::floating_pointが使用できます。