模板与泛型编程

Posted tianzeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板与泛型编程相关的知识,希望对你有一定的参考价值。

  C++ templates的最初发展动机很直接:让我们得以建立“类型安全”的容器如vector,list和map。然而当愈多人用上templates,他们发现templates有能力完成愈多可能的变化。容器当然很好,但泛型编程——写出的代码和其所处理的对象类型彼此独立——更好。STL算法如for_each, find 和 merge 就是这一类编程的成果。最终人们发现,C++ template机制自身是一部完整的图灵机:它可以被用来计算任何可计算的值。于是导出了模板元编程,创造出“在C++编译器内执行并于编译完成时停止执行”的程序。容器反倒只成为C++ template 上的一小部分。然而,尽管template 的应用如此宽广,有一组核心观念一直支撑着所有基于template的编程。那些观念便是本章焦点。

条款41 : 了解隐式接口和编译期多态

  面向对象编程世界总是以显式接口和运行期动态解决问题。如下代码所示:

class Widget
{
    public:
        Widget();
        virtual ~Widget();
        virtual std::size_t size() const;
        virtual void normalize();
        void swap(Widget& other);     // 条款25
        .....
};

void doProcessing(Widget& w)
{
    if (w.size() > 10 && w != someNastyWidget)
    {
        Widget temp(w);
        temp.normalize();
        temp.swap(w);
    }
}

  1.由于w的类型被声明为Widget,所以w必须支持Widget接口。我们可以在源码中找出这个接口,看看它是什么样子,所以我们称为一个显式接口,也就是它在源码中明确可见。

  2.由于Widget的某些成员函数是virtual,w对那些函数的调用将表现出运行期多态,也就是说将于运行期根据w的动态类型(条款37)决定究竟调用哪一个函数。

  Templates及泛型编程的世界,与面向对象有根本不同。在此世界中显式接口和运行期多态仍然存在,但重要性降低。反倒是隐式接口和编译器多态更显重要了。如下:

template<typename T>
void doProcessing(T& w)
{
    if (w.size() > 10 && w != someNastyWidget)
    {
        Widget temp(w);
        temp.normalize();
        temp.swap(w);
    }
}

  3.w 必须支持哪一种接口,系由template中执行于w身上的操作来决定。本例看来w的类型T好像必须支持size,normalize和swap成员函数,copying函数(用来建立temp),不等比较(用来比较someNasty-Widget)等等。这一组表达式(对此template而言必须有效编译)便是T必须支持的一组隐式接口。

  4.凡涉及w的任何函数调用,例如operator>和operator!=,有可能造成template具现化,使这些调用得以成功。这样的具现行为发生在编译期。“以不同的template参数具现化function templates(函数模板)”会导致调用不同的函数,这个便是所谓的编译期多态。(“哪一个函数应该被调用”——发生在编译期; “哪一个virtual函数该被绑定”——发生在运行期)。

  通常,显式接口由函数签名式(也就是函数名称、参数类型、返回类型)构成。

  隐式接口就完全不同了。它并不基于函数签名式,而是由有效表达式组成。

  template参数身上的隐式接口,就像class对象身上的显示接口一个样真实,二者都在编译期完成检查。无法在template中使用“不支持template所要求之隐式接口”的对象,代码编译通不过。

请记住:

  1. classes 和 templates 都支持接口和多态。

  2. 对classes而言接口是显式的,以函数签名为中心。多态则是通过virtual函数发生于运行期。

  3. 对template参数而言,接口是隐式的,奠基于有效表达式。多态则是通过template具现化和函数重载解析发生于编译期。 

 

以上是关于模板与泛型编程的主要内容,如果未能解决你的问题,请参考以下文章

c++模板与泛型编程

模板与泛型编程

模板与泛型编程——定义模板

模板与泛型编程1(函数模板)

第十六章 模板与泛型编程

模板与泛型编程——模板实参推断