I have a generalized modulo struct called quotient_ring
. The relevant bits are shown below.
template <typename R = long long>
struct quotient_ring{
using Q = quotient_ring;
R x, m;
...
template <typename T>
friend constexpr std::basic_ostream<T> &operator<< (std::basic_ostream<T> &str, const Q &q){
return str << '(' << q.x << ")%(" << q.m << ')';
}
};
This operator <<
would print something like 2
mod 7
as (2)%(7)
. The reason I need the brackets is because the type R
can become very nested. However, if R
is only an arithmetic type, such as long long
, I would like to print without the brackets. I found that one way to accomplish this is as follows.
template <typename T>
friend constexpr std::basic_ostream<T> &operator<< (std::basic_ostream<T> &str, const Q &q){
if constexpr (std::is_arithmetic<R>::value) return str << q.x << '%' << q.m;
else return str << '(' << q.x << ")%(" << q.m << ')';
}
I think this is a fine solution. However, I would like to know if the same can be achieved by means of template specialization. I tend to personally like template specialization more than branching on type traits.