我正在尝试为锈蚀迭代器实现C++ 差异 algo。默认情况下,std::adjacent_different在容器中使用当前值减去它以前的值,类似于,如果我们有[5, 7, 16],那么在adjacent_difference之后,我们得到[5, 7-5, 16-7]
我尝试用铁锈作为迭代器扩展,但是发现Iterator::Item - Iterator::Item是std::ops::Sub::Output,为了使Iterator::next返回类型高兴,我必须做一些奇怪的事情,比如Some(iter_item_value - <I as Iterator>::Item::default())来获得正确的哥德波特类型。
struct AdjacentDifference<I>
where I: Iterator
{
prev: Option<I::Item>,
it: I,
}
impl<I> Iterator for AdjacentDifference<I>
where I: Iterator, <I as Iterator>::Item: std::ops::Sub + Default + Copy,
{
type Item = <<I as Iterator>::Item as std::ops::Sub>::Output;
fn next(&mut self) -> Option<Self::Item> {
match (self.it.next(), self.prev) {
(None, _) => None,
(Some(i), Some(p)) => {
let r = i - p;
self.prev = Some(i);
Some(r)
}
(Some(i), None) => {
self.prev = Some(i);
Some(i - <I as Iterator>::Item::default()) // <<- really?
}
}
}
}
trait AdjacentDifferenceExt: Iterator where Self: Sized,
{
fn adjacent_difference(self) -> AdjacentDifference<Self>
where <Self as Iterator>::Item: Copy,
{
AdjacentDifference {
prev: None,
it: self,
}
}
}
impl<I> AdjacentDifferenceExt for I where I: Iterator {}它能工作,但我不太喜欢这个代码,我做错了吗?有什么更好的方法来实现这一点吗?
发布于 2022-10-30 14:50:11
有多种方法可以解决这个问题。
例如,一个选项就是指定减法具有与元素本身相同的类型:
impl<I> Iterator for AdjacentDifference<I>
where
I: Iterator,
I::Item: std::ops::Sub<Output = I::Item> + Copy,
{
type Item = <<I as Iterator>::Item as std::ops::Sub>::Output;
fn next(&mut self) -> Option<Self::Item> {
match (self.it.next(), self.prev) {
(None, _) => None,
(Some(i), Some(p)) => {
let r = i - p;
self.prev = Some(i);
Some(r)
}
(Some(i), None) => {
self.prev = Some(i);
Some(i)
}
}
}
}这限制了您可以使用的类型(例如,您将不能使用Instant - Instant = Duration),但是对于大多数类型来说,这是可以的。
另一个选项是指定迭代器元素类型可以通过From转换为减法类型。
impl<I> Iterator for AdjacentDifference<I>
where
I: Iterator,
I::Item: std::ops::Sub + Copy,
<I::Item as std::ops::Sub>::Output: From<I::Item>,
{
type Item = <<I as Iterator>::Item as std::ops::Sub>::Output;
fn next(&mut self) -> Option<Self::Item> {
match (self.it.next(), self.prev) {
(None, _) => None,
(Some(i), Some(p)) => {
let r = i - p;
self.prev = Some(i);
Some(r)
}
(Some(i), None) => {
self.prev = Some(i);
Some(i.into())
}
}
}
}这将隐式地适用于减法类型是元素类型的情况下,感谢包层impl From for T。
https://stackoverflow.com/questions/74253913
复制相似问题