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

Do we really need to implicitly convert ranges adaptors to bool?

由于 ranges::view_interface has an 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; }));

虽然这看起来很方便,但我们真的需要这个功能吗?原因是传统的STL容器如std::vector,或者常用的视图如std::string_view,并没有这种转换为bool的功能,看起来有些不一致。而且直接调用.empty()或者ranges::empty判断一个区间是否为空似乎更直观

另外,这个隐式转换maybe也会造成混淆:

static_assert(!views::empty<int>);

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

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

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

... custom view types can inher[i]t from view_interface to get a host of useful member functions, like .front(), .back(), .empty(), .size(), .operator[], and even an explicit conversion to bool so that view types can be used in if statements

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

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


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