繁体   English   中英

如何编写 c++ function 什么可以返回迭代器或 reverse_iterator

[英]How to write a c++ function what can return either iterator or reverse_iterator

据我所知,在 c++ 中没有涵盖迭代器和 reverse_iterator 的通用基础 class。

到目前为止我看到的唯一建议是使用模板来解决这个问题( 如何编写一个 function 以通用方式采用迭代器或集合?

但是,此解决方案似乎对我不起作用。

class MyClass
{
    template<typename Iter> Iter* generate_iterator(...params...)
    {
        //returns either a vector::iterator or vector::reverse_iterator
    }
    template<typename Iter> void do_stuff(Iter *begin, Iter *end)
    {
        //does stuff between elements specified by begin and end
        //I would like this function to remain agnostic of which direction it is working in!
    }
    void caller()
    {
        //I would like this function to remain agnostic of which direction it is working in too...
           do_stuff(generate_iterator(blah),generate_iterator(foo));
    }
};

在这种情况下,generate_iterator() 不能按需要使用,因为编译器抱怨“generate_iterator 不是 class MyClass 的成员”大概是因为我没有指定它(实际上我不能因为调用者应该不知道迭代器类型)。

任何人都可以帮忙吗? 提前致谢!

编辑:正如 Mark B 指出的,generate_iterator 必须返回一个指针——现在更正了

更新:刚开始使用这个http://thbecker.net/free_software_utilities/type_erasure_for_cpp_iterators/start_page.html它似乎工作......

您可以创建自己的迭代器 class 知道如何 go 双向。 封装这两种类型的迭代器和内部 select ,无论您使用哪一种进行初始化。

这是一个开始:

template<typename Container>
class BiIterator
{
public:
    BiIterator(Container::iterator i) : m_fwd(i), m_isforward(true) {}
    BiIterator(Container::reverse_iterator i) : m_rev(i), m_isforward(false) {}
    bool operator==(const BiIterator & left, const BiIterator & right);
    Container::value_type & operator*()
    {
        if (m_isforward)
            return *m_fwd;
        return *m_rev;
    }
    const Container::value_type & operator*() const;
    BiIterator & operator++()
    {
        if (m_isforward)
            ++m_fwd;
        else
            ++m_rev;
        return *this;
    }
private:
    Container::iterator         m_fwd;
    Container::reverse_iterator m_rev;
    bool                        m_isforward;
};

在 C++ 中,您不能编写返回两种不同类型的 function。 在您的模板情况下,它将根据实例化返回一个或另一个。 你可能会返回一个指向多态迭代器的基指针,但这会让我问你在这里真正想要做什么。 即使是标准容器也不会尝试这样做:它们已经beginrbegin正确区分。 我建议有两个独立的函数,每个函数都做正确的事情,并根据上下文的指示返回一种类型的迭代器或另一种。

另外,请注意,您不能隐式确定仅用于 function 的返回类型的类型的模板实例化。

通过使用 boost tuple 和 boost any,你的问题可以很容易地解决。 我使用 boost::any 写了一个例子,见下文:

#include <boost/any.hpp>
using boost::any_cast;
#define MSG(msg) cout << msg << endl;
boost::any getIterator(std::vector<int>& vec, bool bReverse)
{
    if(!bReverse)
        return boost::any(vec.begin());
    else
        return boost::any(vec.rbegin());
}

int main() 
{
    std::vector<int> myvec;
    myvec.push_back(1);
    myvec.push_back(2);
    myvec.push_back(3);


    typedef std::vector<int>::iterator vecIter;
    typedef std::vector<int>::reverse_iterator vecRIter;
    try
    {
        boost::any iter  = getIterator(myvec, false);
        boost::any iter2 = getIterator(myvec, true);
        vecIter  it1 = any_cast<vecIter>(iter);
        vecRIter it2 = any_cast<vecRIter>(iter2);
        MSG(*it1);//output 1
        MSG(*it2);//output 3
        return true;
    }
    catch(const boost::bad_any_cast &)
    {
        return false;
    }
}

使用boost::variantboost::any

boost::variant< reverse_iterator, iterator >
generate_iterator(...) {
  if(...) return iterator();
  else return reverse_iterator();
}

// user code
boost::variant< reverse_iterator, iterator > v = generate_iterator();

if(reverse_iterator* it = boost::get<reverse_iterator>(v))
  ...;
else if(...)
  ...;

尽管通过访问者可以更好地访问该variant

缺点是您需要一些样板来提取正确的类型,这正是为什么像any_iterator这样的东西可能是更明智的选择的原因。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM