我们为什么使用概念和约束

Why do we use Concept&Constraint

本文关键字:约束 为什么 我们      更新时间:2023-10-16

我真的不明白为什么C++20提供这样的功能。我需要有人指出如何优雅地使用此功能。 下面是一个示例:

template<typename T>
concept LessCompareable=requires(const T& lhs, const T& rhs)
{
{lhs<rhs}->bool;
};

现在我已经定义了一个概念。 然后,我将像这样约束一个函数模板: (好吧,让我们将其命名为comp,实际上它就像std::min一样)

template<typename T>
const T& comp(const T& a , const T& b) requires LessCompareable<T>
{return a<b?a:b;}

所以问题是如果你这样称呼它

std::thread a,b;
cout<<comp(a,b);

发生兼容错误

但是如果我们不使用约束,CE 也会发生。

所以这让我很困惑,他们都有CE,那我为什么要使用约束呢?

我想如果我想清理错误消息,我可以使用 SFINAE。

约束的目的是允许您使用内置语言构造指定操作的前置条件。编译器可以检查这些前提条件,并且:

  1. 您将收到一条明确的错误消息。
  2. 过载
  3. 分辨率中不会考虑过载(是的,另一种执行 SFINAE 的方法)。

错误消息很好,但是#2的新前提条件检查是其中的真正内容。在 C++20 之前,您需要执行的操作才能获得相同的效果,如下所示:

template<typename T,
std::enable_if_t<has_less_than_op<T>::value, int> = 0>
const T& comp(const T& a , const T& b) 
{return a<b?a:b;}

它笨拙而繁琐,你需要对SFINAE技术有先见之明,才能理解为什么有人会写这样的东西。它非常专家友好。模板已经具有这种力量,但这是一个历史巧合。概念(精简版)和约束提供了以更自然的方式表达相同事物的能力。

将上述内容与您的 OP 或这个进行比较:

template<LessCompareable T>
const T& comp(const T& a , const T& b)
{return a<b?a:b;}

哪种选择表达得更清楚?我会说,不是旧技术。

与现有方法相比,概念的一个重要特征是将编译错误缩小到定义时间和实例化时间。目前,所有错误都是在模板实例化时生成的,很难检测模板定义是否格式不正确,从未编译或准备的参数是否不合适。概念的主要目标是区分两种类型的错误。