为什么要使用Concept&Constraint
Why do we use Concept&Constraint
我不太明白为什么 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,那我为什么要用constraints呢?
我想如果我想清理错误信息,我可以使用 SFINAE。
约束的目的是允许您指定 pre-conditions 使用 built-in 语言结构的操作。这些 pre-conditions 可以由编译器检查,并且:
- 您会收到一条明确的错误消息。
- 过载决议不会考虑过载(是的,还有一种方法可以执行 SFINAE)。
错误消息很不错,但是针对 #2 的新 pre-condition 检查才是真正的内容。在 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;}
哪个选项表达得更清楚?不是旧技术,我会说。
与现有方法相比,概念的一个重要特征是将编译错误减少到定义时间和实例化时间。目前所有的错误都是在模板实例化时产生的,很难检测模板定义是否为ill-formed,从不编译或准备的参数不合适。概念的主要目标是分离两种类型的错误。
我不太明白为什么 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,那我为什么要用constraints呢?
我想如果我想清理错误信息,我可以使用 SFINAE。
约束的目的是允许您指定 pre-conditions 使用 built-in 语言结构的操作。这些 pre-conditions 可以由编译器检查,并且:
- 您会收到一条明确的错误消息。
- 过载决议不会考虑过载(是的,还有一种方法可以执行 SFINAE)。
错误消息很不错,但是针对 #2 的新 pre-condition 检查才是真正的内容。在 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;}
哪个选项表达得更清楚?不是旧技术,我会说。
与现有方法相比,概念的一个重要特征是将编译错误减少到定义时间和实例化时间。目前所有的错误都是在模板实例化时产生的,很难检测模板定义是否为ill-formed,从不编译或准备的参数不合适。概念的主要目标是分离两种类型的错误。