2012-01-06 5 views
3

사용한 fnc에서 iterator를 반환하고이 iterator를 일부 문자로 반환하지만이 fnc가 반환 한 후에 반환 된 반복자는 더 이상 해당 문자를 가리 키지 않습니다 . 내가 도대체 ​​뭘 잘못하고있는 겁니까?반환하는 iterator가 무효화 된 것으로 보입니다

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 
} 

아이디어가 있으십니까?

+11

컴파일하고 문제를 보여줍니다 최소한의 케이스를 제공하세요. –

+1

"일부 위치"가 문자열의 길이를 초과하지 않는 경우 (즉, 같거나 지나치게 :: end()) 이상이 아닌 경우가 될 수 있습니다. –

답변

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 : 나는 순간에 준수 컴파일러하지 않는 한 나는, auto (11) C++의 제거있어)

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 (완벽하게 유효한 변환)으로 변환됩니다.

편집 :

#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

을 주장 :는 값으로 return_iterator()line 매개 변수를 전달하기 위해 수정 된 다음 버전의 출력을 살펴, 내 점을 보여주기 위해 이제 실패합니다. 또한 *line.begin()의 주소가 다릅니다.

+1

서명이'const std :: string &'을 사용한다고해도, iterator를 반환하면 함수가'return_iterator ("foo")'또는 임시 문자열을 생성하고 상수 참조를 전달하는 것과 비슷한 어떤 것이라도 문제가 발생할 수 있습니다. 임시. 나는 이것이 OP의 실제 코드에서 일어난다 고 추측하고 있습니다. –

+0

@ AndréCaron : 참. 그것은 문제 일 수 있습니다. –

관련 문제