我们真的需要将范围适配器隐式转换为 bool 吗?

康桓瑋*_*康桓瑋 19 c++ c++20 std-ranges

由于ranges::view_interface有一个explicit operator bool()函数,这使得大多数 C++20 范围适配器能够转换为bool

https://godbolt.org/z/ccbPrG51c

static_assert(views::iota(0));
static_assert("hello"sv | views::split(' '));
static_assert(views::single(0) | std::views::transform([](auto) { return 0; }));
Run Code Online (Sandbox Code Playgroud)

虽然这看起来很方便,但我们真的需要这个功能吗?原因是传统的STL容器比如std::vector,或者常用的视图比如std::string_view,没有这个转换为 的功能bool,看起来有些不协调。只是调用.empty()ranges::empty直接确定范围是否为空似乎更直观。

此外,这种隐式转换也可能会引起混淆:

static_assert(!views::empty<int>);
Run Code Online (Sandbox Code Playgroud)

那么,为什么ranges::view_interface提供这个operator bool功能呢?有没有实际的用例?

请注意,这可能是一个基于意见的问题,但我想知道view_interface提供operator bool.

cig*_*ien 14

来自Eric Niebler 的这篇文,他的 range-V3 库严重影响了 C++20 的范围

... 自定义视图类型可以继承 [i]t fromview_interface以获取大量有用的成员函数,例如.front(), .back(), .empty(), .size(), .operator[]甚至显式转换 tobool以便可以在 if 语句中使用视图类型

// Boolean conversion operator comes from view_interface:
if ( auto evens = vec | view::filter(is_even) ) {
  // yup, we have some evens. Do something.
}
Run Code Online (Sandbox Code Playgroud)

因此,这至少是将范围视图转换为bool. 请注意,这是一个显式转换,因此它仅发生在执行转换的上下文中,例如通过显式转换,或在if条件中使用它,或static_assert在您的问题中使用它。


正如 Eric 在对此答案的评论中所提到的,对于所述用例,此功能实际上不再有用,大概是因为我们现在将 if-with-initializers 作为语言构造,因此此功能可能会被弃用。

  • 是的,它不再需要,并且可能会被弃用。 (2认同)