定义遍历函数的const和非const版本

时间:2016-09-02 08:22:55

标签: c++ c++11 lambda const traversal

我有一个类似于列表的数据结构:

template<typename T>
struct node {
  T val;
  unique_ptr<node<T>> next;
};

和一个简单的遍历函数:

template<typename T, typename UnaryOp>
void traverse(node<T>& list, UnaryOp op) {
  node<T>* current = &list;
  while(current) {
    op(*current);
    current = current->next.get();
}

我现在需要constnon-const 版本的traverse函数,该函数接受const node<T>& list或{{1}根据上下文,最好避免代码重复。怎么可以实现呢?

1 个答案:

答案 0 :(得分:1)

一种可能的解决方案是创建一个静态模板函数,该函数将*this作为转发引用:

class node
{
private:
    template <typename TSelf>
    static void traverse_impl(TSelf& self, node<T>& list, UnaryOp op)
    {
        node<T>* current = &list;
        while(current)
        {
            op(*current);
            current = current->next.get();
        }
    }

public:
    void traverse(node<T>& list, UnaryOp op)
    {
        traverse_impl(*this, list, op);
    }

    void traverse(node<T>& list, UnaryOp op) const
    {
        traverse_impl(*this, list, op);
    }
};

这可以使用https://google.github.io/android-testing-support-library/docs/espresso/setup/index.html - 简而言之,TSelf会接受const和非const引用。

如果您需要访问this内的traverse_impl成员,请使用self.member

此外,您可以使用std::conditional内的traverse_impl或类似设施执行不同的操作,具体取决于const的{​​{1}}。您还可以使用转发引用TSelf,并处理template argument deduction rulesref-qualifiers移动TSelf&&的情况。