我有一个称为quotient_ring
的广义模结构。相关位如下所示。
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
,我想不带括号而打印。我发现实现此目的的一种方法如下。
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 << ')';
}
我认为这是一个很好的解决方案。但是,我想知道是否可以通过模板专门化来实现。我个人更喜欢模板专业化,而不是分支于类型特征。
答案 0 :(得分:2)
我个人更喜欢模板专业化,而不是分支类型特征。
为什么? $ cat file
OCCUPY 12 EVERY PIC 32(12). SUNNY
OCCUPY 45 EVERY
PIC X(21). SUNNY
$ sed -Ez 's/(OCCUPY\s+[0-9]+\s+EVERY)\s+(PIC\s+[^)]+\))/\2 \1/g' file
PIC 32(12) OCCUPY 12 EVERY. SUNNY
PIC X(21) OCCUPY 45 EVERY. SUNNY
$ sed -Ez 's/((\S+\s+){2}\S+)\s+(\S+\s+\S+\))/\3 \1/g' file
PIC 32(12) OCCUPY 12 EVERY. SUNNY
PIC X(21) OCCUPY 45 EVERY. SUNNY
$ sed -Ez 's/(OCCUPY)\s+([0-9]+)\s+(EVERY)\s+(PIC)\s+([^)]+\))/\4 \5 \1 \2 \3/g' file
PIC 32(12) OCCUPY 12 EVERY. SUNNY
PIC X(21) OCCUPY 45 EVERY. SUNNY
$ sed -Ez 's/(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+\))/\4 \5 \1 \2 \3/g' file
PIC 32(12) OCCUPY 12 EVERY. SUNNY
PIC X(21) OCCUPY 45 EVERY. SUNNY
是编译时分支。等效的SFINAE的可读性要差得多。
if constexpr
可能我建议在输出中放置一些空格(例如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)
}
)以使其更具可读性吗?