C++ 成语运用到 C#: CRTP (curiously recurring template pattern) 的应用,以及实现非类型泛型参数

2017-08-03 20:31:26 +08:00
 geelaw

这篇帖子翻译自 这篇博文

转到 C♯ 上写密码学代码,C♯ 泛型比 C++ 模板的限制多很多,比如 对于泛型参数,不能使用(算术)运算符。这导致类似

template <unsigned p>
struct Z
{
    // Z/pZ 这个环的实现。
};

template <typename TRing>
struct Foo
{
    /* TRing 是一个环的类型,可以当成黑箱
     */

    struct AffineTransform
    {
        TRing k, b;
        TRing operator () (TRing x) const
        {
            return k * x + b;
        }
    };

    static std::function<TRing(TRing)>
    CreateAffineTransform(TRing k, TRing b)
    {
        AffineTransform aff;
        aff.k = k;
        aff.b = b;
        return aff;
    }
};

在 C♯ 里不可行。解决方法是 CRTP,让类型自带接口,替代运算符

另一个问题:C♯ 里面的泛型参数只能是类型,不能是值,这样 Z<p> 的实现看起来就要分开写好几次。

有两个丑的绕过方法:

第一个方法和 C♯ 本身没有关系了,而且回到原始人时代;第二个方法除了降低运行时效率之外,还会一下子把一个环元素的大小 扩大一倍

答案是把数值 放进一个类型里面,再借助 CRTP 书写辅助工具,可以让这个基础设施非常好用

具体请移步 原文

2087 次点击
所在节点    分享创造
3 条回复
gnaggnoyil
2017-08-04 01:55:58 +08:00
这让我想起了这个帖子:

https://www.zhihu.com/question/27421302
geelaw
2017-08-04 04:48:46 +08:00
@gnaggnoyil 老技巧了,我后来改写了博文,和现在的翻译总结不太一致了。

实际上 C# 里面也到处都是 CRTP,比如 IComparable 模式。
lindexi
2017-08-04 20:34:43 +08:00
泛型很厉害,至少可以不写工厂

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/380246

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX