6

我真的不明白为什么 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。

4

2 回答 2

20

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

  1. 您将收到一条明确的错误消息。
  2. 在重载决议中将不考虑重载(是的,另一种执行 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;}

哪个选项表达的更清楚?不是旧技术,我会说。

于 2018-04-05T09:07:54.587 回答
1

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

于 2018-04-05T13:23:37.223 回答