如何编写一个可以返回迭代器或reverse_iterator的c++函数
How to write a c++ function what can return either iterator or reverse_iterator
据我所知,在c++中,没有同时涵盖迭代器和reverse_iterator的公共基类。
到目前为止,我看到的唯一建议是使用模板来解决这个问题(如何编写一个以通用方式使用迭代器或集合的函数?(
然而,这个解决方案似乎对我不起作用。
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_titerator((不能根据需要使用,因为编译器抱怨"generate_t迭代器不是类MyClass的成员",可能是因为我没有指定它(实际上我不能指定它,因为调用者应该不知道迭代器类型(。
有人能帮忙吗?提前感谢!
edit:正如Mark B所指出的,generate_titerator必须返回一个指针-现在已更正
更新:刚刚开始使用http://thbecker.net/free_software_utilities/type_erasure_for_cpp_iterators/start_page.html它似乎起作用了。。。
您可以创建自己的迭代器类,它知道如何双向运行。封装这两种类型的迭代器,并在内部选择使用哪种迭代器进行初始化。
这里有一个开始:
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++中,不能编写返回两种不同类型的函数。在您的模板案例中,它将根据实例化返回一个或另一个。您可能会返回一个多态迭代器的基指针,但这会让我问您在这里真正想做什么。即使是标准容器也不会尝试这样做:它们有begin
和rbegin
来正确区分。我建议使用两个独立的函数,每个函数都做正确的事情,并根据上下文指示返回一种类型的迭代器或另一种类型。
另外,请注意,不能隐式地确定只用于函数返回类型的类型的模板实例化。
通过使用boost元组和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::variant或boost::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
这样的东西可能是一个更明智的选择的原因。
- 使用std::multimap迭代器创建std::list
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++中带有List类的迭代器Segfault
- 如何在c++迭代器类型中包装std::chrono
- 集合上的输出迭代器:assign和increment迭代器
- Boost Spirit,获取迭代器内部语义动作
- 对于set上的循环-获取next元素迭代器
- 为什么output_editor Concept不需要output_e迭代器标记
- c++17文件系统::recursive_directory迭代器()在mac上没有给出这样的目录,但在windows上
- 使用迭代器时如何访问对象在向量中的位置?
- std::vector::迭代器是否可以合法地作为指针
- 跟随整数索引列表的自定义类迭代器
- 不明白迭代器,引用和指针失效,一个例子
- 我可以使用反向迭代器作为ForwardIt吗
- ESP8266单片机矢量迭代器的C++问题
- 如何在C++中将迭代器作为函数参数传递
- 是否应避免从非常量迭代器转换为常量迭代器?
- 如何在 c++ 中将字符串迭代器变量传递给函数?
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 为什么 C++ std::unordered_map 从 emplace/ 找到返回一个迭代器?