• 第2章 类模板:2.3 类模板的局部使用


    2.3 Partial Usage of Class Templates

    2.3 类模板的局部使用

    A class template usually applies multiple operations on the template arguments it is instantiated for (including construction and destruction). This might lead to the impression that these template arguments have to provide all operations necessary for all member functions of a class template. But this is not the case: Template arguments only have to provide all necessary operations that are needed (instead of that could be needed).

    类模板通常会对其实例化的模板参数请求多种操作(包括构造和析构)。这可能会给我们有这样的印象:这些模板参数必须提供类模板的所有成员函数所需的所有操作。但是事实并非如此:模板参数只需提供所需要的所有必要操作(而不是可能需要的操作)。

    If, for example, class Stack<> would provide a member function printOn() to print the whole stack content, which calls operator<< for each element:

    例如,如果类Stack<>提供了一个printOn()成员函数来打印整个栈内容,那么该函数将调用每个元素的“operator<<”运算符:

    template<typename T>
    class Stack {
        …
        void printOn() (std::ostream& strm) const {
            for (T const& elem : elems) {
                strm << elem << ’ ’; // call << for each element
            }
        }
    };

    You can still use this class for elements that don’t have operator<< defined:

    对于未定义“<<”运算符的元素,你也仍然可以使用此类:

    Stack<std::pair< int, int>> ps; // note: std::pair<> has no operator<< defined
    ps.push({4, 5}); // OK
    ps.push({6, 7}); // OK
    std::cout << ps.top().first << ’
    ’; // OK
    std::cout << ps.top().second << ’
    ’; // OK

    Only if you call printOn() for such a stack, the code will produce an error, because it can’t instantiate the call of operator<< for this specific element type:

    只有当你调用了此类栈的printOn()函数,这段代码才会产生错误。因为无法实例化这种特定元素类型的“<<”运算符的调用。

    ps.printOn(std::cout); // 错误: 元素类型不支持operator<<操作

    2.3.1 Concepts

    2.3.1 Concept关键字

    This raises the question: How do we know which operations are required for a template to be able to get instantiated? The term concept is often used to denote a set of constraints that is repeatedly required in a template library. For example, the C++ standard library relies on such concepts as random access iterator and default constructible.

    这就提出了一个问题:我们如何知道模板需要哪些操作才能被实例化?术语concept通常用于表示模板库中可重复使用的一组约束(译注:concept表示施加于模板参数上的一种约束,如T必须支持operator<<等等)。例如,C++标准库依赖的concepts: 随机访问迭代器(random access iterator)和可默认构造 (default constructible)。

    Currently (i.e., as of C++17), concepts can more or less only be expressed in the documentation (e.g., code comments). This can become a significant problem because failures to follow constraints can lead to terrible error messages (see Section 9.4 on page 143).

    For years, there have also been approaches and trials to support the definition and validation of concepts as a language feature. However, up to C++17 no such approach was standardized yet.

    当前(即从C++17开始),concepts或多或少只能在文档中表达(例如代码注释)。这可能会成为一个严重的问题,因为未遵守约束条件可能导致可怕的错误信息(见第143页9.4节)。多年来,也有一些方法和尝试来支持将concept的定义和验证作为一种语言特性。但直到C++17这类方法还没有被标准化。

    Since C++11, you can at least check for some basic constraints by using the static_assert keyword and some predefined type traits. For example:

    从C++11开始,你至少可以通过使用static_assert关键字和一些预定义的类型萃取工具来检查一些基本的约束。例如:

    template<typename T>
    class C
    {
        static_assert(std::is_default_constructible<T>::value,
                       "Class C requires default-constructible elements");
        …
    };

    Without this assertion the compilation will still fail, if the default constructor is required. However, the error message then might contain the entire template instantiation history from the initial cause of the instantiation down to the actual template definition in which the error was detected (see Section 9.4 on page 143).

    如果没有这个断言,若需要默认构造函数,编译仍将失败。但是随后的错误信息可能包含在模板实例化的整个历史中,这个阶段会从最初的实例化语句到实际检测错误的模板定义处(请参阅第143页的9.4节)。

    However, more complicated code is necessary to check, for example, objects of type T provide a specific member function or that they can be compared using operator <. See Section 19.6.3 on page 436 for a detailed example of such code.

    但是,更复杂的代码需要检查。例如,T类型对象提供特定的成员函数,或者可以使用“<“运算符来比较(有关此类例码的详细示例,请参阅第436页19.6.3节)。

    See Appendix E for a detailed discussion of concepts for C++.

    关于C++中concepts的详细讨论请参阅附录E。

  • 相关阅读:
    软件开发(目录规范)
    面向对象编程(UDP协议)
    Django+uwsgi+Nginx
    Django(图书管理系统)
    orm(Manager isn't accessible via %s instances" % cls.__name)报错
    Django(图书管理系统)#转
    docker(mysql-redmine)
    Django(orm)转
    Django(多表查询操作)
    Oracle(ERROR SP2-0642)
  • 原文地址:https://www.cnblogs.com/5iedu/p/12708958.html
Copyright © 2020-2023  润新知