为什么C++没有std::invocable_r概念?

Afi*_*efh 12 c++ language-design c++-concepts c++20

C++20 添加了概念,标准库中包含了相当多的概念。有一个概念特别引起了我的注意:std::invocable,它验证可以使用一组参数来调用函子。

std::invocable只是 的语法糖std::is_invocable。然而,标准库进一步定义了std::is_invocable_r哪些测试函子是否可以使用一组参数调用,而且一旦调用它就返回特定类型。nothrow这两个实用程序也有不同的版本。然而,标准中没有定义等效的概念。

该标准没有定义这些概念是否有原因,或者只是一个疏忽?是否有一些普通读者没有注意到的细节导致委员会决定不包括这些内容?

Jan*_*tke 13

概念库的设计方法比类型特征的设计方法要简约得多。例如,没有与特征std::arithmetic相匹配的概念std::is_arithmetic。这有两个原因:

  1. 它可以简单地由std::is_arithmetic、 或std::integral和构造而成std::floating_point
  2. 目前尚不清楚应优先选择这些结构中的哪一个。

另请参阅:C++ 标准库中会有算术类型的概念吗?

std::invocable一般问题和便利概念

std::invocable及其_r变体也存在类似的问题nothrow。您可以简单地构造一个这样的概念:

template <typename T, typename R, typename... Args>
concept invocable_r = invocable<T, Args...> && requires (Args&&... args) {
    { invoke(forward<Args>(args...)) } -> convertible_to<R>;
};
Run Code Online (Sandbox Code Playgroud)

然而,目前还不清楚这是否是最终的实施。您也可以根据 来构造它std::invoke_r,目前还不清楚是否std::convertible_to仍然应该使用。

总之,概念库不包含存在以下问题的概念:

  1. 这个概念可以很容易地从其他概念构建出来,所以它只是为了方便而存在。这包括nothrow变体、_r变体、析取std::arithmetic等。用户可以自己制作这些。

  2. 有多种可能的实现,但尚不清楚哪一种应该纳入标准库。请记住,定义概念的确切方式可能会使其比另一个概念受到更多限制,因此实现细节很重要。

请注意,概念标准化很大程度上是由范围库驱动的,std::invocable_r对于限制范围并不重要。由instd::invoke使用。std::indirect_result_tstd::indirectly_writable

标准化提案的难度

最后但并非最不重要的一点是,请记住,标准化任何语言功能都是一项艰巨的任务。提案越细小,就越容易获得委员会的通过。如果现在有人提出一个提供此类便利概念的提案,那么它很有可能会成功,但是,在当时,这将是一项艰巨的任务,这会增加提案的规模(P9898:标准库概念)相当多。

  • “用户可以自己制作这些。” 如果新的 C++ 程序员能够使用概念作为抽象层,而不必了解底层(且不太直观)C++11 元编程库,这难道不是令人希望的吗?其他几点都很有道理。 (3认同)
  • @TooTone 是的,当然。即使实现相对简单,拥有额外的便利概念也是有好处的。这就是为什么我说便利概念的提案可能会取得成功。在当时,要标准化它需要付出太多的努力,而回报却太少。 (3认同)
  • 人们还可以想象一个_external_(仅头文件)库提供便利的概念;并非所有内容都需要成为_Standard_库的一部分。 (2认同)