gpt4 book ai didi

c++ - 为什么 range::iota_view 的构造函数不将参数移动到成员变量?

转载 作者:行者123 更新时间:2023-12-04 11:39:15 27 4
gpt4 key购买 nike

[range.iota.view] , iota_view 的著名构造函数定义如下(强调我的):

constexpr explicit iota_view(W value);

Preconditions: Bound denotes unreachable_­sentinel_­t or Bound() isreachable from value.

Effects: Initializes value_­ with value.


为什么构造函数要用 value初始化 value_而不是 std::move(value) ?在我看来,使用 std::move(value) 似乎更有效率因为类型 W 内部可能存在内存分配,这可能会导致复制构造的开销。
此外,其他范围适配器,例如 filter_view transform_view 和他们的 iterators在构造过程中也直接将接受的参数移动到成员变量中,因此这里似乎存在不一致。
那么为什么 iota_view复制构造其成员变量而不是移动构造?
这背后有何考虑?

最佳答案

受到两个赞成票并且没有人反对我的鼓励,这是我以更详细的形式对 OP 发表的评论。

So why does iota_view copy-construct its member variables instead of move-construct?


这不是这里所暗示的。

Initializes value_­ with value.


这仅意味着 value ,构造函数参数的名称,用于初始化 value_ ,成员(member)。它没有说明这是如何发生的。
这就是标准库规范的大部分工作方式:它仅强制执行严格的最低限度以确保所需的语义和行为,为实现者提供尽可能多的回旋余地。没有什么可以阻止 iota_view从使用移动语义,没有义务这样做。
快速查看 MSVC 的实现表明它确实使用了移动构造:
        constexpr explicit iota_view(_Wi _Value_) noexcept(
is_nothrow_move_constructible_v<_Wi>&& is_nothrow_default_constructible_v<_Bo>) // strengthened
: _Value(_STD move(_Value_)) {}
现在,显而易见的问题变成了:“为什么 filter_viewtransform_view 指定必须使用 std::move()?”
注意以下是 投机 ,基于这种区分是有意为之的假设,而不是一种或另一种疏忽。
虽然选择如此严格的措辞可能还有其他一些原因,但我相信类声明之间的差异为我们对明显的不一致提供了合理的解释:
template<weakly_­incrementable W, semiregular Bound = unreachable_sentinel_t>
requires weakly-equality-comparable-with<W, Bound> && copyable<W>
class iota_view : public view_interface<iota_view<W, Bound>> {...};

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>> {...};

template<input_­range V, copy_­constructible F>
requires view<V> && is_object_v<F> &&
regular_­invocable<F&, range_reference_t<V>> &&
can-reference<invoke_result_t<F&, range_reference_t<V>>>
class transform_view : public view_interface<transform_view<V, F>> {
View 在哪里:
template<class T>
concept view =
range<T> && movable<T> && enable_view<T>;
最大的不同在于 iota_viewWcopyable<> , 而 filter_viewtransform_view只期待 movable<>V .因此,后面的这些必须以适应仅移动类型(如 std::unique_ptr<> )的方式编写。
iota_view必须使用匹配 copyable<> 的类型概念,从语义的角度来看,复制构造或移动构造都是可以接受的。决定权留给实现者,即使没有明显的理由不使用移动构造。

关于c++ - 为什么 range::iota_view 的构造函数不将参数移动到成员变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68167390/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com