为什么概念细化不能使用简洁的语法

问题描述 投票:15回答:1

在完善概念时,在标准中始终如一地完成的方式是完全写出正在改进的概念。例如,在[concepts.integral]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>;

SignedIntegral2似乎与SignedIntegral具有相同的明显含义,但它甚至没有在clang上编译。是否有一个原因?

c++ c++-concepts c++20
1个回答
18
投票

由于SignedIntegral2[temp.concept]/4的声明形成不良:

概念不应具有相关约束。

了解其原因非常重要。概念基本上是谓词。他们的工作是采取一系列论点(最常见的是一系列类型)并说出这个概念是否满足。但请考虑这两种不同实现的答案:

  • SignedIntegral<int32_t>true
  • SignedIntegral<uint32_t>false
  • SignedIntegral<string>false

但:

  • SignedIntegral2<int32_t>true
  • SignedIntegral2<uint32_t>false
  • SignedIntegral2<string>是......未定义的

概念的全部意义在于约束。在SignedIntegral2中提出的替代,简洁声明将类型参数T约束为Integral。由于string不满足Integral,我们甚至不能问这个问题是否是SignedIntegral2

换句话说,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>; }

重要的是概念总是总函数,这就是不允许相关约束的原因。


请注意,为了概念满足的目的,肯定有可能将“undefined”视为false,但这会给包含规则增加额外的皱纹,这肯定是非常重要的实现复杂性。一些未来的标准肯定可能允许它们。我的水晶球目前在商店,所以我不能肯定地说。

© www.soinside.com 2019 - 2024. All rights reserved.