当前位置: 首页 > 知识库问答 >
问题:

概念和模板约束之间有什么区别?

韦飞尘
2023-03-14

共有1个答案

滕胜涝
2023-03-14

以下信息已过时。它需要根据最新的概念Lite草案进行更新。

限制建议第3节对此作了合理的深入探讨。

概念提案暂时被搁置,希望约束(即概念-精简)能在更短的时间内充实和实施,目前的目标至少是C++14中的某些内容。约束建议的目的是作为一个平稳过渡到概念的稍后定义。约束是概念提案的一部分,是概念定义中的必要组成部分。

  1. 约束-类型的静态可计算属性上的谓词。纯粹的句法要求。不是域抽象。
  2. 公理--假定为真的类型的语义要求。未静态检查。
  3. 概念-算法对其参数的一般性、抽象要求。根据约束和公理定义。

因此,如果将公理(语义属性)添加到约束(语法属性)中,就会得到概念。

概念精简方案只给我们带来了第一部分,约束,但这是迈向全面概念的重要和必要的一步。

template <typename Cont>
  requires Sortable<Cont>()
void sort(Cont& container);
template <Sortable Cont>
void sort(Cont& container);

现在,如果您试图将不认为sortable的任何内容传递给这个函数,您将得到一个很好的错误,它立即告诉您为t推导的类型不是sortable类型。如果在C++11中这样做,就会在sort函数中抛出一些对任何人都没有意义的可怕错误。

约束谓词非常类似于类型特征。他们采取一些模板参数类型,并给你一些关于它的信息。约束试图回答以下类型的问题:

  1. 此类型是否重载了某某运算符?
  2. 这些类型可以用作此运算符的操作数吗?
  3. 此类型是否具有某某特征?
  4. 这个常数表达式等于那个常数表达式吗?(对于非类型模板参数)
  5. 此类型是否有返回该类型的名为yada-yada的函数?
  6. 此类型是否满足用作该类型的所有语法要求?

>

  • equality_carable :检查该类型是否具有==同一类型的两个操作数。

    equality_carable :检查是否存在具有给定类型的左右操作数的==

    arithmetic :检查类型是否为算术类型。

    same :检查给定的类型是否相同。

    您可以使用一个特殊的概念--GCC的Lite构建来尝试所有这些。

    现在我们进入概念之外的一切--精简提案。这甚至比未来本身更具未来感。从现在开始,一切都可能发生很大的变化。

    template<typename T>
    axiom Greater(T x, T y) {
      (x>y) == (y<x);
    }
    
      null

    也就是说,它们完全关注类型的语义和对这些类型的操作。这些东西不能静态检查。如果需要检查这一点,类型必须以某种方式宣布它遵守这些语义。

    以下是公理的一些常见示例:

    >

  • equivalence_relation:如果两个对象比较==,则它们是等效的。

    作为一个示例,考虑以下有序概念:

    concept Ordered<Regular T> {
      requires constraint Less<T>;
      requires axiom Strict_total_order<less<T>, T>;
      requires axiom Greater<T>;
      requires axiom Less_equal<T>;
      requires axiom Greater_equal<T>;
    }
    

    首先,要使模板类型Tordered,它还必须满足regular概念的要求。regular概念是一个非常基本的要求,即类型行为良好--它可以被构造、销毁、复制和比较。

    除了这些要求之外,ordered还要求t满足一个约束和四个公理:

      null

    以下是一些概念示例

    >

  • 常规类型是可构造、可析构、可复制的,并且可以进行比较。

    ordered类型支持运算符<,并且具有严格的总排序和其他排序语义。

    >

  • 它不提供概念定义语言。

    约束不是概念图。用户不需要将它们的类型专门标注为满足某些约束。使用简单的编译时语言功能静态地检查它们。

    模板的实现不受其模板参数上的约束的约束。也就是说,如果函数模板对受约束类型的对象做了任何它不应该做的事情,编译器就无法诊断。一个功能齐全的概念提案将能够做到这一点。

  •  类似资料:
    • 问题内容: 如果我想要一个可以表示多种可能类型的类型,则s似乎就是我的表示方式: 可以是或。 我注意到尽管s允许可选的var-arg参数,但它们似乎也做同样的事情: 双方并似乎只被允许采取的类型和。 这两种方式有什么区别,何时应首选? 问题答案: 的类型必须在给定范围内的多种用途之间保持一致,而的类型则不一致。 使用类型作为函数参数时,参数以及返回类型都可以不同: 将其与参数类型必须匹配的类似情况

    • 问题内容: 在此示例中: 无法编译为: 而被编译器接受。 这个答案说明唯一的区别是,与不同,它允许您稍后引用类型,似乎并非如此。 是什么区别,并在这种情况下,为什么不第一编译? 问题答案: 通过使用以下签名定义方法: 并像这样调用它: 在jls§8.1.2中,我们发现(有趣的部分被我加粗了): 通用类声明定义了一组参数化类型(第4.5节), 每种可能通过类型arguments调用类型参数节的类型

    • 我对面向对象编程有这种困惑。对于我编写的一些代码,我必须回答一些问题: 此代码中使用的OOP原则是什么 它们是如何应用的 解释此代码中使用的OOP概念 在这里,我不理解这两个词“原则”和“概念”之间的区别。它们是一样的吗?还是不同? 我知道有4个面向对象的原则。 继承权 在我的代码中,我有setter方法、getter方法、抽象类、类之间的继承。所以我的回答是: > 继承,抽象,封装,多态性。 我

    • 问题内容: Python模块和Python包之间有什么区别? 问题答案: 模块是单个文件(一个或多个文件),可在一个导入下导入并使用。例如 包是目录中提供包层次结构的模块的集合。

    • 问题内容: 我已经看到许多项目使用 模块而不是 标准库中的模块。另外,有许多不同的模块。为什么要使用这些替代方法而不是标准库中的替代方法? 问题答案: 是 ,已添加到stdlib中。但是自从2.6中添加以来,它具有处理更多Python版本(2.4+)的优势。 的更新频率也比Python高,因此,如果您需要(或想要)最新版本,则尽可能使用它自己。 我认为,一种好的做法是将其中一个作为后备。

    • 这个问题似乎离题了,因为它缺乏足够的信息来诊断问题 更详细地描述你的问题,或者在问题本身中包含一个最小的例子。 其中Fragment和Intent是构建类,FragmentABC是用户定义的类。 它非常基本,但仍然无法找出合理的差异来证明实例化。想知道这两种说法的区别是什么,请在你提供的答案中描述一下。