首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我怎么能分辨铁锈的两个性状有相同的类型?

我怎么能分辨铁锈的两个性状有相同的类型?
EN

Stack Overflow用户
提问于 2022-10-30 14:30:56
回答 1查看 73关注 0票数 1

我正在尝试为锈蚀迭代器实现C++ 差异 algo。默认情况下,std::adjacent_different在容器中使用当前值减去它以前的值,类似于,如果我们有[5, 7, 16],那么在adjacent_difference之后,我们得到[5, 7-5, 16-7]

我尝试用铁锈作为迭代器扩展,但是发现Iterator::Item - Iterator::Itemstd::ops::Sub::Output,为了使Iterator::next返回类型高兴,我必须做一些奇怪的事情,比如Some(iter_item_value - <I as Iterator>::Item::default())来获得正确的哥德波特类型。

代码语言:javascript
复制
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 {}

它能工作,但我不太喜欢这个代码,我做错了吗?有什么更好的方法来实现这一点吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-30 14:50:11

有多种方法可以解决这个问题。

例如,一个选项就是指定减法具有与元素本身相同的类型:

代码语言:javascript
复制
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转换为减法类型。

代码语言:javascript
复制
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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74253913

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档