函数返回C++中的迭代器
function returning iterator in C++
下面是一个返回迭代器的Java方法
vector<string> types;
// some code here
Iterator Union::types()
{
return types.iterator();
}
我想把这段代码翻译成C++。如何从这个方法返回向量的迭代器?
这将返回一个迭代器到types
:的开头
std::vector<string>::iterator Union::types()
{
return types.begin();
}
然而,调用者也需要知道向量types
的end()
。Java的Iterator
有一个方法hasNext()
:这在C++中不存在。
您可以更改Union::types()
以返回一个范围:
std::pair<std::vector<std::string>::iterator,
std::vector<std::string>::iterator> Union::types()
{
return std::make_pair(types.begin(), types.end());
}
std::pair<std::vector<std::string>::iterator,
std::vector<std::string>::iterator> p = Union::types();
for (; p.first != p.second; p.first++)
{
}
您需要一个begin
和end
方法:
std::vector<string>::iterator Union::begin()
{
return types.begin();
}
std::vector<string>::iterator Union::end()
{
return types.end();
}
为了完整起见,您可能还想要const
版本的
std::vector<string>::const_iterator Union::begin()const
{
return types.begin();
}
std::vector<string>::const_iterator Union::end()const
{
return types.end();
}
假设类型是类Union的一个属性,这是一种很好的、符合STL的方法,处理它的方法是:
class Union
{
std::vector<std::string> types
public:
typedef std::vector< std::string >::iterator iterator;
iterator begin() { return types.begin(); }
iterator end() { return types.end(); }
};
联合是其成员的容器。我将使用begin
和end
分别向第一个和最后一个成员返回迭代器。
类型列表不是联合的主要可迭代属性。因此,我将自己使用以下内容,并为成员数据本身保留普通的begin
和end
。
std::vector<string>::const_iterator Union::types_begin() const {
return types.begin();
}
std::vector<string>::const_iterator Union::types_end() const {
return types.end();
}
返回迭代器很容易。例如,您可以返回向量类型中的第一个迭代器:
std::vector<std::string> types;
// some code here
std::vector<std::string>::iterator Union::returnTheBeginIterator()
{
return types.begin();
}
Java与C++
但是C++迭代器不是Java迭代器:它们的使用方式不同。
在Java(IIRC)中,您更像是一个枚举器,也就是说,您使用方法"next"从一个项迭代到下一个项。因此,返回Java迭代器就足以从开始到结束进行迭代。
在C++中,迭代器被设计为表现得像一个超级指针。因此,它通常"指向"该值,并使用运算符++、--等(取决于迭代器的确切类型),可以将迭代器移动到"指向"容器中的下一个、上一个等值。
让我们迭代
通常,您希望从开始到结束进行迭代。
这样,您需要返回整个集合(如果您希望它是只读的,则返回为"const"),并让用户按照他/她想要的方式进行迭代。
或者,您可以返回两个迭代器,一个用于开头,一个用作结尾。所以你可以有:
std::vector<std::string>::iterator Union::typesBegin()
{
return types.begin();
}
std::vector<std::string>::iterator Union::typesEnd()
{
return types.end();
}
您可以在C++03:中从头迭代到尾
// alias, because the full declaration is too long
typedef std::vector<std::string> VecStr ;
void foo(Union & p_union)
{
VecStr::iterator it = p_union.typesBegin() ;
VecStr::iterator itEnd = p_union.typesEnd() ;
for(; it != itEnd; ++it)
{
// here, "*it" is the current string item
std::cout << "The current value is " << *it << ".n" ;
}
}
C++11版本
如果在C++11中提供完整的容器而不是仅提供迭代器,则会变得更容易,因为您可以使用循环的范围(如Java和C#中的foreach):
void foo(std::vector<std::string> & p_types)
{
for(std::string & item : p_types)
{
// here, "item " is the current string item
std::cout << "The current value is " << item << ".n" ;
}
}
附言:Johannes Schaub-litb在任何可能的情况下使用"const"限定词都是正确的。我没有这样做,因为我想避免淡化代码,但最终,"const"是你的朋友。
您可以按照以下进行操作
std::vector<std::string> types
std::vector<std::string>::iterator Union::types(){
return types.begin();
}
- 使用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/ 找到返回一个迭代器?