繁体   English   中英

c ++朋友运算符模板特化

[英]c++ friend operator template specialization

我有一个名为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 as (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 << ')';
}

我认为这是一个很好的解决方案。 但是,我想知道是否可以通过模板特化来实现相同的目的。 我个人更喜欢模板专业化而不是类型特征的分支。

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

为什么? if constexpr是一个编译时分支 等效的 SFINAE 可读性要差得多。

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) )以使其更具可读性?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM