微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

为什么 range::unique_copy 不能与 std::ostream_iterator 一起使用?

如何解决为什么 range::unique_copy 不能与 std::ostream_iterator 一起使用?

[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,它只是抱怨实例化value_typeindirectly_readable_traits<ostream_iterator<int>>中没有same_as<iter_value_t<_Iter>,iter_value_t<_Out>

为什么上述代码在 C++20 中格式错误

解决方法

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。