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

我无法掌握通用编程的某个方面,正如“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));
}
点赞