加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

在C通用编程中重载增量运算符

发布时间:2020-12-16 07:21:08 所属栏目:百科 来源:网络整理
导读:我无法掌握通用编程的某个方面,正如“C编程语言”一书中所解释的那样. 在第24.2节中. “算法和提升”是一种在一系列对象中累积值的通用算法(在其他语言中也称为reduce,fold,sum,aggregate): // quoted from "The C++ Programming Language" 4th ed. Section
我无法掌握通用编程的某个方面,正如“C编程语言”一书中所解释的那样.

在第24.2节中. “算法和提升”是一种在一系列对象中累积值的通用算法(在其他语言中也称为reduce,fold,sum,aggregate):

// quoted from "The C++ Programming Language" 4th ed. Section 24.2 p. 702
template<typename Iter,typename Val>
Val sum(Iter first,Iter last)
{
    Val s=0;
    while(first!=last) {
        s = s + *first;
        ++first;
    }
    return s;
}

此函数模板适用于任意类型,如double值数组或用户定义类型的链接列表,如下一段中所示:

// quoted from "The C++ Programming Language" 4th ed. Section 24.2 p. 703
struct Node {
    Node* next; int data;
};
Node* operator++(Node* p) {return p->next;}
int operator*(Node* p) {return p->data;}
Node* end(Node* lst) {return nullptr;}

为了使用上面的函数模板“sum”,上面的代码重载了类型Node *的和*运算符.我的理解是不能在指针类型上重载这些运算符.我的编译器(MSVC和GCC)证实了这一点,他们产生了以下错误消息:

'Node* operator++(Node*)' must have an argument of class or enumerated type
'int operator*(Node*)' must have an argument of class or enumerated type

我在这里错过了什么吗?

或者我应该给编辑写一封信?

解决方法

标准库中的迭代器功能通过名为std :: iterator_traits的标准模板类表示.

您既可以对其进行特化,也可以允许默认的特化从迭代器类中推导出类型(这意味着您必须正确编写迭代器).

例:

#include <iterator>

struct Node {
    Node* next; int data;
};

struct NodeIterator {

    using value_type = int;

    NodeIterator(Node* nodes = nullptr) : p_(nodes) {}

    NodeIterator& operator++() {
        p_ = p_->next;
    }

    value_type operator*() const {
        return p_->data;
    }

    bool operator==(NodeIterator& other) const {
        return p_ == other.p_;
    }

    bool operator!=(NodeIterator& other) const {
        return p_ != other.p_;
    }

    Node* p_;
};

namespace std {
    template<> struct iterator_traits<NodeIterator>
    {
        using difference_type = std::ptrdiff_t;
        using value_type = NodeIterator::value_type;
        using pointer = value_type*;
        using reference = const value_type&;
        using iterator_category = std::forward_iterator_tag;
    };
}

NodeIterator end(Node* lst) {return { nullptr };}


template<typename Iter>
auto sum(Iter first,Iter last) -> typename std::iterator_traits<Iter>::value_type
{
    using Val = typename std::iterator_traits<Iter>::value_type;
    Val s=0;
    while(first!=last) {
        s = s + *first;
        ++first;
    }
    return s;
}

int sumNodes(Node* nodes)
{
    return sum(NodeIterator(nodes),end(nodes));
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读