`inline constexpr bool` 和 `concept` 之间有什么区别吗?

tej*_*jas 6 c++ c++-concepts c++20

template<typename T>
inline constexpr bool is_int_v1 = std::is_same_v<T, int>;

template<typename T>
concept is_int_v2 = std::is_same_v<T, int>;
Run Code Online (Sandbox Code Playgroud)

inline constexpr bool在这个代码块中,格式和格式有什么区别concept。其中一个优于另一个还是它们等效?

Nic*_*las 11

有很多差异。变量就是变量;即使它们是inline constexpr,它们仍然是变量。它们代表对象,您可以获取它们的地址。

\n

Aconcept根本不是变量。您不能获取它的地址或用它做任何类似的事情。concepts 具有特殊的语法规则,而void func(ConceptName auto x);变量却没有。

\n

变量可以是模板并进行模板专门化。concept我们不必变得专业化;这是故意的。一个特定的概念名称与一个约束表达式相关联,无论赋予它什么模板参数。

\n

但最重要的区别是在实例化期间concept要遵循特殊的包含规则

\n

当您尝试实例化受约束的模板时,C++ 将执行多个步骤来确定哪个匹配模板是可以应用的“最受约束”的版本。在解析要实例化的模板期间,最受约束的形式被赋予更大的权重。

\n

std::signed_integral<T>是根据 定义的std::integral<T>

\n
template<class T>\n  concept signed_\xc2\xadintegral = integral<T> && is_signed_v<T>;\n
Run Code Online (Sandbox Code Playgroud)\n

这意味着,如果某种类型T满足signed_integral,那么它必然满足integral。如果您有同一模板的两个版本,一个受 约束,integral另一个受 约束signed_integral,则传递unsigned int必然会实例化第一个模板。

\n

int满足这两个概念。但由于编译器知道signed_integralcontains integral,因此它被认为是“更受约束”。因此,如果一个类型同时满足这两个条件,则该模板将被优先考虑。

\n

只有您使用concept. 如果这些只是inline constexpr变量,那么尝试使用int将会出现编译错误,因为这两个约束都被赋予相同的权重。

\n

inline constexpr变量本质上是约束系统的黑匣子。concepts 是约束系统的一部分。

\n