c ++朋友运算符模板专业化 [英] c++ friend operator template specialization

查看:72
本文介绍了c ++朋友运算符模板专业化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个称为 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.

推荐答案

我个人更喜欢模板专业化,而不是分支类型特征.

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 ++朋友运算符模板专业化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆