返回迭代器似乎会使其无效
Returning iterator seems to invalidate it
我在使用我的fnc之后从它返回迭代器,这个迭代器在返回点指向某个字符,但在这个fnc返回它之后,返回的迭代器不再指向那个字符。我做错了什么?
typename std::string::const_iterator return_iterator(const std::string& line)
{
auto beg = line.begin();
/*here I'm moving this iterator and assing to it i.e.*/
beg = line.begin() + some_position;
return beg;//at this point it points to a character
}
void other_fnc(const std::string& line)
{
auto pos = return_iterator(line);//after this fnc returns pos points to some rubbish
}
有什么想法吗?
由于您发布的示例代码没有编译(typename std::string::const_iterator
应该只是std::string::const_iterator
),并且修复此错误可以使代码按预期运行,我猜实际代码有点不同。
在我看来,这听起来像是std::string
参数按值复制的情况,并且在访问const_iterator
之前,引用计数以某种方式中断。例如,此签名:
std::string::const_iterator return_iterator(std::string line)
// ^ Notice: Not passing by
// reference
按值传递字符串。由于COW,副本是共享的,但在函数调用line.begin()
的那一刻,就会调用非常数字符串成员函数std::string::begin()
,这意味着通常会创建底层字符串的新副本。然后将返回的非常数iterator
隐式转换为const_iterator
(完全有效的转换)。
编辑:为了证明我的观点,请查看以下版本的输出,该版本被修改为按值将line
参数传递给return_iterator()
:
#include <cassert>
#include <string>
#include <iostream>
std::string::const_iterator return_iterator(std::string line)
{
std::string::const_iterator beg = line.begin();
std::cout << "In return_iterator(), &(*line.begin()) is " << static_cast<const void *>(&*beg) << 'n';
/*here I'm moving this iterator and assing to it i.e.*/
beg = line.begin() + 3;
return beg;//at this point it points to a character
}
void other_fnc(const std::string& line)
{
std::string::const_iterator pos = return_iterator(line);//after this fnc returns pos points to some rubbish
std::cout << "In other_fnc(), &(*line.begin()) is " << static_cast<const void *>(&*line.begin()) << 'n';
assert(*pos == line[3]);
}
int main()
{
std::string line = "This is a test.";
other_fnc(line);
}
http://codepad.org/K9yaWqWA
断言现在失败了。另外,请注意*line.begin()
的地址是不同的。
我认为,实际的代码可能有模板(typename
碎片),并且可能在返回类型的函数参数中没有正确引用它们。
以下代码按预期工作:
const int some_position = 2;
template <typename T>
typename T::const_iterator return_iterator(const T& line)
{
typename T::const_iterator beg = line.begin();
beg = line.begin() + some_position;
return beg;//at this point it points to a character
}
void other_fnc(const std::string& line)
{
std::string::const_iterator pos = return_iterator(line);
std::cout << "character to 2: " << *pos << std::endl;
}
int main()
{
std::string str = "Hello world";
other_fnc(str);
}
根据它验证你的代码。如果你正在做其他事情,请更新你的问题。
(附言:我去掉了C++11的auto
,因为我现在没有兼容的编译器)
相关文章:
- 修改 std::vector 会使迭代器无效吗?
- 二进制表达式的操作数无效 - 使用 for 和迭代器
- 无效迭代器上的算术
- 插入 boost::multi_index 后迭代器变得无效?
- 在擦除或修改作为不同索引键的值时,boost::multi_index 迭代器是否无效?
- 如果迭代器没有因插入而无效,则使用std::find和C::insert()是线程安全的
- 如何获得保证的无效迭代器(用于向量)
- 在这种情况下,可以比较无效的迭代器
- 为什么映射迭代器显示基本操作数无效错误
- 在向量中无效的迭代器
- 迭代器擦除矢量中的元素无效,但它不会崩溃
- 我可以在 std::list 中移动元素而不会使迭代器或引用无效,但是如何移动呢?
- 如果迭代器的迭代器永远不会无效,则是STD :: MAP访问线程安全
- 如何避免使用“ReplaceInstWithValue()”使迭代器无效
- 当此容器也是容器的元素时,为什么容器的迭代器无效
- std :: move()会使迭代器无效
- 无效迭代器:如何在第一次使用时获取一些调试信息
- 检测环形缓冲区的无效迭代器
- 哪些操作为无效迭代器定义
- 在解引用无效迭代器时强制异常