关于约束和概念

时间:2018-04-05 08:54:38

标签: c++ c++20

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

发生了complie错误

但如果我们不使用约束,CE也会出现。

这让我感到困惑,他们两个都有CE,那为什么我应该使用约束呢?

2 个答案:

答案 0 :(得分:17)

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

  1. 您将收到明确的错误消息。
  2. 过载分辨率不会考虑过载(是的,还有一种方法可以做SFINAE)。
  3. 错误消息很好,但是#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技术有所了解,才能理解为什么会有人写这样的东西。它非常友好。模板已经拥有了这种力量,但这是一个历史巧合。概念(lite)和约束使得能够以更自然的方式表达相同的事物。

    将上述内容与您的OP或以下内容进行比较:

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

    哪种替代方案表达的东西更清晰?我不是说旧技术。

答案 1 :(得分:1)

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