【问题标题】:Why ranges::unique_copy cannot work with std::ostream_iterator?为什么 range::unique_copy 不能与 std::ostream_iterator 一起使用?
【发布时间】:2021-08-14 16:59:22
【问题描述】:

[alg.unique]中,ranges::unique_copy的签名定义为:

template<input_­iterator I, sentinel_­for<I> S, weakly_­incrementable O, class Proj = identity,
         indirect_­equivalence_­relation<projected<I, Proj>> C = ranges::equal_to>
  requires indirectly_­copyable<I, O> &&
           (forward_­iterator<I> ||
            (input_­iterator<O> && same_­as<iter_value_t<I>, iter_value_t<O>>) ||
            indirectly_­copyable_­storable<I, O>)
  constexpr ranges::unique_copy_result<I, O>
    ranges::unique_copy(I first, S last, O result, C comp = {}, Proj proj = {});

但是我发现当I只是一个input_iteratorO只是一个output_iterator时,下面的代码编译失败:

std::istringstream str("42 42 42");
std::ranges::unique_copy(
  std::istream_iterator<int>(str), 
  std::istream_iterator<int>(),
  std::ostream_iterator<int>(std::cout, " "));

gcc 和 msvc 都使用 (godbolt) 拒绝它:

error: no type named 'value_type' in 'using type = struct std::indirectly_readable_traits<std::ostream_iterator<int> >' {aka 'struct std::indirectly_readable_traits<std::ostream_iterator<int> >'}
 1436 |                            && same_as<iter_value_t<_Iter>, iter_value_t<_Out>>)

奇怪的是,这里的错误信息并没有显示constraints not satisfied,它只是在实例化same_as&lt;iter_value_t&lt;_Iter&gt;, iter_value_t&lt;_Out&gt;时抱怨indirectly_readable_traits&lt;ostream_iterator&lt;int&gt;&gt;中没有value_type

为什么上面的代码在 C++20 中格式不正确?

【问题讨论】:

    标签: c++ stl iterator c++20


    【解决方案1】:

    这是两个实现中的错误。两者都包含相当于

    if constexpr (input_­iterator<O> && same_­as<iter_value_t<I>, iter_value_t<O>>) 
    

    在约束中这很好,因为通过短路逐渐检查约束满足(并且在任何情况下替换失败只会导致约束评估为false),所以如果O不是输入迭代器,我们不会询问其(可能不存在的)值类型。在if constexpr 中没有短路,因此整个表达式被替换为当场不正确。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-28
      • 2018-02-25
      • 2018-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多