我在使用它之后从我的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
}
有什么想法吗?
答案 0 :(得分:1)
由于您发布的示例代码未编译(typename std::string::const_iterator
应该只是std::string::const_iterator
),修复此错误允许代码run as expected,我猜测实际的代码有点不同。
这听起来像是std::string
参数被值复制的情况,并且引用计数在访问const_iterator
之前以某种方式被中断。例如,这个签名:
std::string::const_iterator return_iterator(std::string line)
// ^ Notice: Not passing by
// reference
按值传递字符串。由于COW,副本是共享的,但是当函数调用line.begin()
时,非const 字符串成员函数std::string::begin()
被调用,这意味着该副本的新副本通常会创建基础字符串。然后,返回的非const 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);
}
断言现在失败了。另请注意,*line.begin()
的地址不同。
答案 1 :(得分:0)
我假设,实际代码可能有模板(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);
}
根据它验证您的代码。如果您正在做其他事情,请更新您的问题。
(PS:我摆脱了C ++ 11的auto
,因为我目前没有兼容的编译器)