问题描述
我有一个称为 quotient_ring
的通用模结构.相关位如下所示.
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 << ')';
}
};
此运算符<<
会将 2
mod 7
之类的内容打印为(2)%(7).我需要括号的原因是因为
R
类型可以变得非常嵌套.但是,如果 R
只是一种算术类型,例如 long long
,我想在不带括号的情况下进行打印.我发现实现此目的的一种方法如下.
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.
推荐答案
为什么?
如果constexpr
是编译时分支.等效的SFINAE的可读性要差得多.
Why?
if constexpr
is a compile-time branch. The equivalent SFINAE is far less readable.
template <typename R = long long>
struct quotient_ring{
using Q = quotient_ring;
R x, m;
template <typename Char>
friend constexpr std::enable_if_t<
std::is_arithmetic_v<R>,
std::basic_ostream<Char> &
>
operator<< (std::basic_ostream<Char> &str, const Q &q){
return str << q.x << '%' << q.m;;
}
template <typename Char>
friend constexpr std::enable_if_t<
!std::is_arithmetic_v<R>,
std::basic_ostream<Char> &
>
operator<< (std::basic_ostream<Char> &str, const Q &q){
return str << '(' << q.x << ")%(" << q.m << ')';
}
};
int main() {
quotient_ring<quotient_ring<>> ring{
{1, 2},
{3, 4}
};
std::cout << ring << '\n'; // (1%2)%(3%4)
}
我建议您在输出中添加一些空格(例如
(1%2)%(3%4)
)以使其更具可读性吗?
Might I suggest putting some spaces in the output (like
(1 % 2) % (3 % 4)
) to make it more readable?
这篇关于c ++朋友运算符模板专业化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!