如何解决为什么 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_iterator
而 O
只是一个 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_type
时indirectly_readable_traits<ostream_iterator<int>>
中没有same_as<iter_value_t<_Iter>,iter_value_t<_Out>
。
解决方法
这是两个实现中的一个错误。两者都包含相当于
if constexpr (input_iterator<O> && same_as<iter_value_t<I>,iter_value_t<O>>)
在约束中这很好,因为约束满足是通过短路逐步检查的(并且在任何情况下替换失败只会导致约束评估为 false
),所以如果 O
不是我们不会询问其(可能不存在的)值类型的输入迭代器。在 if constexpr
中没有短路,因此整个表达式被替换为当场错误形成。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。