Вы можете создать свой постоянный класс int, похожий на std::integral_constant
, но дополненный необходимой функцией, например:
template <int N> struct int_c
{
static constexpr int value = N;
};
template <int N1, int N2>
constexpr int_c<N1 + N2> operator + (int_c<N1>, int_c<N2>) { return {}; }
template <int N>
std::ostream& operator << (std::ostream& os, int_c<N>) { return os << N; }
Затем измените свой класс, чтобы иметь близкий интерфейс, особенно для конструктора, добавьте метод фабрики:
template <int A_, int B_>
class One {
public:
static constexpr int_c<A_> A{};
static constexpr int_c<B_> B{};
const int C;
One(int C) : C(C) {}
template <typename IA, typename IB>
static One<IA::value, IB::value> Create(IA, IB, int C) { return {C}; }
};
class Two {
public:
const int A;
const int B;
const int C;
Two(int A, int B, int C) : A(A), B(B), C(C) {}
static Two Create(int A, int B, int C) { return {A, B, C}; }
};
Тогда ваш общий код может выглядеть так:
template <typename T1, typename T2>
auto min(const T1& a, const T2& b) {
if (a.C < b.C) {
return T1::Create(a.A + b.A, a.B + b.B, a.C);
} else {
return T1::Create(a.A + b.A, a.B + b.B, b.C);
}
}
Демо