potisanのプログラミングメモ

趣味のプログラマーがプログラミング関係で気になったことや調べたことをいつでも忘れられるようにメモするブログです。

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が使用できます。