LoginSignup
0
0

More than 5 years have passed since last update.

templateの数値引数に制約をかける

Posted at

整数管理クラスを作る時、最大値と最小値をtemplate引数に持ってきて、その最大値と最小値の大小関係の制約をかけたかったんですが、templateの開きカッコと閉じカッコ扱いされてできなかったのでこれ作りました

Compassion.hpp
#ifndef __COMPASSION_HPP__
#define __COMPASSION_HPP__
#include <type_traits>

namespace standard {
    namespace compassion {
        namespace {
            template<typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
            constexpr bool large_impl(const T a, const T b) { return a > b; }
            template<typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
            constexpr bool small_impl(const T a, const T b) { return a < b; }
            template<typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
            constexpr bool e_large_impl(const T a, const T b) { return a >= b; }
            template<typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
            constexpr bool e_small_impl(const T a, const T b) { return a <= b; }
            template<typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
            constexpr bool eq_impl(const T a, const T b) { return a == b; }
            template<typename T, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
            constexpr bool ne_impl(const T a, const T b) { return a != b; }
        }
        template<typename T, T a, T b, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
        constexpr bool large = large_impl<T>(a, b);
        template<typename T, T a, T b, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
        constexpr bool small = small_impl<T>(a, b);
        template<typename T, T a, T b, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
        constexpr bool e_large = e_large_impl<T>(a, b);
        template<typename T, T a, T b, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
        constexpr bool e_small = e_small_impl<T>(a, b);
        template<typename T, T a, T b, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
        constexpr bool eq = eq_impl<T>(a, b);
        template<typename T, T a, T b, std::enable_if_t<std::is_integral_v<T>, std::nullptr_t> = nullptr>
        constexpr bool ne = ne_impl<T>(a, b);
    }
}
#endif

これを作るのに参考にしたのは、std::is_arithmetic_v等の実装です

使い方はこんな感じですね

sample.cpp
template<typename T, T max, T min, std::enable_if_t<std::is_arithmetic_v<T> && standard::compassion::e_large<T, max, min>, std::nullptr_t> = nullptr>
class Integer {
    // 実装を記述する
};

compassionの変数たちのtemplate引数の片方を数字にしても使えます。ただし、floatとdoubleは使えません

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0