C++ 为什么可以';t概念细化使用简洁的语法
在细化概念时,标准中一贯采用的方式是完全写出被细化的概念。例如,在中,C++ 为什么可以';t概念细化使用简洁的语法,c++,c++-concepts,c++20,C++,C++ Concepts,C++20,在细化概念时,标准中一贯采用的方式是完全写出被细化的概念。例如,在中,SignedIntegral对Integral进行细化,如下所示: template<class T> concept Integral = is_integral_v<T>; template<class T> concept SignedIntegral = Integral<T> && is_signed_v<T>; 模板 概念积分=是
SignedIntegral
对Integral
进行细化,如下所示:
template<class T>
concept Integral = is_integral_v<T>;
template<class T>
concept SignedIntegral = Integral<T> && is_signed_v<T>;
模板
概念积分=是积分;
模板
概念符号积分=积分&符号化;
为什么精炼的概念不能写成:
template<Integral T>
concept SignedIntegral2 = is_signed_v<T>;
模板
概念签名整数2=是签名的;
SignedIntegral2
似乎有着与SignedIntegral
相同的明显含义,但它甚至不在clang上编译。有什么原因吗?签名的第2部分的声明格式不正确,因为:
概念不应具有相关约束
理解这其中的原因很重要。概念基本上是谓词。他们的工作是获取一系列参数(最常见的是一系列类型),并判断概念是否满足。但是考虑一下这两种不同的实现会给出什么答案:
为SignedIntegral
true
为SignedIntegral
false
为SignedIntegral
false
为SignedIntegral2
true
为SignedIntegral2
false
是。。。未定义SignedIntegral2
SignedIntegral2
中建议的替代方案简洁声明将类型参数T
约束为Integral
。由于字符串
不满足积分
,我们甚至不能问它是否是签名的积分2
换言之,SignedIntegral
是一个总函数,而SignedIntegral2
是一个仅在Integral
类型上定义的部分函数。如果我们将这两个函数都写为实际函数,这一点可能会更清楚:
template <typename T>
constexpr bool SignedIntegral() { return Integral<T> && is_signed_v<T>; }
template <Integral T>
constexpr bool SignedIntegral2() { return is_signed_v<T>; }
模板
constexpr bool SignedIntegral(){return Integral&&is_signed_v;}
模板
constexpr bool SignedIntegral2(){返回值是有符号的}
重要的是,概念始终是总函数,这就是为什么不允许关联约束的原因
注意,出于概念满足的目的,将“undefined”视为
false
当然是可能的扩展,但这会给包容规则增加额外的皱纹,而且实现的复杂性肯定不小。当然,未来的一些标准可能会允许它们。我的水晶球现在在店里,所以我不能肯定 我想我理解你的观点,但是对于非算术类型,不是定义为false
,而是“未定义”?@HolyBlackCat:是的,但是SignedIntegral2
是未定义的,因为对于非整数类型的SignedIntegral2
没有有效的实例化。这就是模板约束失败时的含义。现在,如果有一个单独的SignedIntegral2
定义是不受约束的,那么它可以被实例化。从技术上讲,它不会“未定义”;它会生病的-formed@NicolBolas我没有注意到模板参数是Integral t
,而不是typename t
。我真傻/这实际上是两个独立的问题。“为什么我们不能有约束的概念”和“为什么我们不能将概念上的约束定义为连接”。