C++ 概念复合需求和 return-type-requirements

C++ concepts compound requirements and return-type-requirements

上次我将 C++ 概念与 GCC 和 fconcepts 标志一起使用时,以下代码段用于工作

template <typename T, typename U>
concept equality_comparable = requires(T a, U b) {
  { a == b } -> bool;
  { a != b } -> bool;
};

显然情况不再如此,return-type-requirementcompound requirement 之后现在只能包含类型约束。如果我没记错的话,这基本上意味着使用另一个概念来满足 return-type-requirement.

因此,完全可读且(针对 C++ 标准)的简短代码段变为

template <typename From, typename To>
concept convertible_to = std::is_convertible_v<From, To>;

template <typename T, typename U>
concept equality_comparable = requires(T a, U b) {
  { a == b } -> convertible_to<bool>;
  { a != b } -> convertible_to<bool>;
};

当然,这甚至不是一个完整的实现,但让我们暂时忽略它。有人可以向我解释为什么委员会决定改变它吗?我个人认为 convertible_to 概念中的 "implicitly used template parameter" 非常令人恼火和困惑。

嗯,这到底是什么意思:

template <typename T, typename U>
concept equality_comparable = requires(T a, U b) {
  { a == b } -> bool;
  { a != b } -> bool;
};

这是否意味着 a == b 的类型必须完全 bool,或者这是否意味着如果你衰减类型你会得到 bool(即 const boolbool& 可以),还是可以转换为 bool(即 std::true_type 可以)?我认为从语法上看一点都不清楚——这三者中的任何一个都可能是一个特定概念所需要的(正如 P1452 当时指出的那样,Same<T>ConvertibleTo<T> 在概念中是 40-14)。

该论文还指出,在存在 -> Type 的 Concepts TS 中,我们也有能力编写类似 vector<Concept>... 或 -> vector<Concept> 的内容作为要求。这是一种类型,但对于我们在 P1084 中采用的 decltype(()) 语义来说会非常困难。

基本上我不认为 "perfectly readable" 片段实际上是 - 该语法有多种潜在含义,所有这些都可以是所需的含义,具体取决于上下文。而当时最常用的(same_as<bool>)甚至不是我们这里想要的那个(convertible_to<bool>)。


Personally I find that "implicitly used template parameter" in the convertible_to concept extremely irritating and confusing.

它在 C++ 中很新颖,但我个人认为它在这些情况下读起来非常好。正在看:

{ a == b } -> convertible_to<bool>;

完全按照要求读取:a == b 需要是可转换为 bool 的有效表达式。对于一元概念,它使用法非常好,因为您可以使用它们代替有点无意义的 typename/class 关键字:

template <range R>
void algo(R&& r);

这与其他语言没有什么不同。例如,在 Rust 中:

fn algo<I: Iterator>(i: I)

那里的 "implicitly used template parameter" 是如此隐含以至于它甚至不是 trait declaration 的一部分,它也隐含在那里:

pub trait Iterator { ... }

因此,即使使用更长格式的语法,您仍会编写 where I: Iterator 而在 C++ 中,您仍然会编写 requires range<R>.

这与原始问题没有严格的关系,但我只是觉得添加一些其他颜色很有趣。