C++ 我们为什么要使用概念和;约束

C++ 我们为什么要使用概念和;约束,c++,c++20,C++,C++20,我真的不明白为什么C++20提供这样一个特性。我需要有人指出如何优雅地使用这个功能。 以下是一个例子: template<typename T> concept LessCompareable=requires(const T& lhs, const T& rhs) { {lhs<rhs}->bool; }; 所以问题是如果你把这叫做 std::thread a,b; cout<<comp(a,b); std::线程a、b; c

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

template<typename T>
concept LessCompareable=requires(const T& lhs, const T& rhs)
{
      {lhs<rhs}->bool;
};
所以问题是如果你把这叫做

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

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

  • 您将得到一条清晰的错误消息
  • 过载解决方案中不会考虑过载(是的,还有一种方法可以实现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;}
    
    模板
    施工测试与施工(施工测试与施工、施工测试与施工)
    
    {return a与现有方法相比,概念的一个重要特征是将编译错误缩减到定义时间和实例化时间。目前,所有错误都是在模板实例化时生成的,很难检测模板定义是否格式错误,并且从不编译或准备的参数是否为inap适当。概念的主要目标是区分这两种类型的错误。

    您将更容易理解编译错误,而不是模板库代码中当前的混乱错误。@KenY-N是的,我在cppreference上看到过,但我仍然不知道为什么它更容易理解。当然,CEs要少得多,但我认为我使用模板库代码时也很容易发现复杂的错误。可能有一些复杂的CE我不知道。不可否认,这是这个功能的一个优点,这个评论真的很好。但我想知道是否有一些更大的优点,我想同时好好学习这个功能。然后看看我的文章d表示一个(暗示的)20深实例化堆栈中的约束错误可能很难看,也很难读取。特别是当错误导致编译器在12级左右选择意外重载时。@谢谢,我明白了。很久以前我被问到,我不理解在当时替换基于SFINAE的某些类型检查的意义。但现在我明白了,它不会在清理编译器错误信息中,这是至关重要的。这是否意味着我不应该再使用STD::Enable?IFIt在Type的特性中?@ Jordin,你仍然可以使用它,并且考虑到C++的复杂程度,可能还需要我不知道的。这是为了取代“哈基什”。我们在SFINAE等方面使用它的方式。概念也使定义约束变得更容易。直到C++17,人们不得不使用检测习惯用法或其他黑客定义类,如
    has_less_than_op
    。有了概念,人们可以通过使用
    requires
    子句轻松地陈述期望的成员和函数。
    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;}
    
    template<LessCompareable T>
    const T& comp(const T& a , const T& b)
    {return a<b?a:b;}