我们真的需要将范围适配器隐式转换为 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 作为语言结构,因此此功能可能被弃用。
由于 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 tobool
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 作为语言结构,因此此功能可能被弃用。