由于C++23,view不再需要成为default_constructible。对于范围适配器(如views::filter和views::transform ),它们的默认构造函数是重新定义,如下所示:
template<input_range V, indirect_unary_predicate<iterator_t<V>> Pred>
requires view<V> && is_object_v<Pred>
class filter_view : public view_interface<filter_view<V, Pred>> {
private:
V base_ = V(); // exposition only
copyable-box<Pred> pred_; // exposition only
public:
filter_view() requires default_initializable<V> && default_initializable<Pred> = default;
};由于ref_view的默认构造函数已在p2325r3中删除,这表明应用于lvalue range(如std::vector are 不再 default_constructible )的范围适配器。
std::vector v{1, 2, 3};
auto r = v | std::views::filter([](auto) { return true; });
decltype(r){}; // ok in C++20, error in C++23只有在将范围适配器应用到default_constructible view的(如std::string_view或views::iota(0) )中时,返回的视图才可以是default_constructible。
auto r = std::views::iota(0) | std::views::filter([](auto) { return true; });
decltype(r){}; // ok in C++20 and C++23但是对于这些案例,我实在想不出用例来制作这些view的default_constructible,即使这是可行的。默认情况下,如果我们构造一个view,这意味着我们构建了一个空的view,而将范围适配器应用到空views显然是毫无意义的:
constexpr auto r = std::views::iota(0, 10)
| std::views::transform([](auto x) { return x; });
static_assert(!std::ranges::empty(r));
// views::iota is default-constructible, so r is also default-constructible
static_assert( std::ranges::empty(decltype(r){}));在我看来,C++20中的范围适配器的默认构造函数只是为了满足view,因为view不再需要在C++23中是default_constructible,因此不需要这些适配器的默认构造器存在。
为什么这些范围适配器的默认构造函数在C++23中没有删除,而是变成了约束函数?真的有一种情况要求它是default_constructible吗?这背后有甚麽考虑呢?
发布于 2021-07-11 15:44:08
本文之前的现状是视图必须是默认的可构造的,即使这不是视图可以满足的有意义的需求,导致视图具有一个只能分配给它的单数状态。这并不是很有用(甚至是有害的),这就是为什么这个要求被删除的原因。
但是现在视图仅仅可以是默认的可构造的,问题是什么时候应该使范围适配器默认为可构造的。这个问题的答案更直截了当:如果可以的话,你为什么不让它成为默认的可构造的呢?
如果您使用的是一个视图,transform是默认的可构造视图(假定V是具有有意义的状态的默认可构造的--这并不是不可行的:默认构造的string_view是一个有效的空范围),而且您的函数F也是默认的可构造的(例如,任何捕获--在C++20中是较少的lambda ),那么transform_view<V, F>实际上也应该是默认的。没有太多的理由不这样做,它实际上是自由的,有条件地提供构造函数,它不会造成伤害。
因此,在不提供默认构造函数和有条件地提供默认构造函数(如果这样做是明智的)之间,后者似乎是一个更方便用户的选择。
否则,从库的角度来看,您必须能够以某种方式保证默认构造这样的范围适配器永远不会有用.我不确定你能不能这么做?
注意,这不是C++23的一个新的库特性,而是针对C++20的一个缺陷。
https://stackoverflow.com/questions/68337376
复制相似问题