문제

을 썼어요 몇 가지 기능을 가진 시제품을 다음과 같다:

template <typename input_iterator>
int parse_integer(input_iterator &begin, input_iterator end);

아이디어가 호출자가 제공,문자의 범위와 기능을 해석 문자 정수 값으로 돌아와 그것을 떠나,시작에 지나 마지막 사용된다.예를 들어:

std::string sample_text("123 foo bar");
std::string::const_iterator p(sample_text.begin());
std::string::const_iterator end(sample_text.end());
int i = parse_integer(p, end);

이 떠날 것 i 설정 123 p "가리키는"에 공간 전에 foo.

때문에 나는 말(없이 설명)는것은 나쁜 형태로 전달하는 반복기에 참조.그것은 나쁜 형태?그렇다면 이유는 무엇입니까?

도움이 되었습니까?

해결책

실제로 잘못된 것은 없지만 템플릿의 사용을 확실히 제한 할 것입니다. 당신은 다른 것에 의해 반복되는 반복기를 넣거나 생성 된 것만 큼 v.begin(), 그것들은 시간이되므로. 먼저 먼저 로컬 사본을 만들어야합니다.

한 가지 방법은 과부하입니다.

int parse_integer(input_iterator begin, input_iterator end, 
                  input_iterator &newbegin);

template<typename input_iterator>
int parse_integer(input_iterator begin, input_iterator end) {
    return parse_integer(begin, end, begin);
} 

또 다른 옵션은 숫자가 기록 될 출력 반복기를 갖는 것입니다.

template<typename input_iterator, typename output_iterator>
input_iterator parse_integer(input_iterator begin, input_iterator end,
                             output_iterator out);

새 입력 반복기를 반환 할 반환 값이 있습니다. 그런 다음 인서터 반복기를 사용하여 구문 분석 숫자를 벡터 또는 포인터에 넣어 이미 숫자의 양을 알고 있다면 정수 또는 배열에 직접 넣을 수 있습니다.

int i;
b = parse_integer(b, end, &i);

std::vector<int> numbers;
b = parse_integer(b, end, std::back_inserter(numbers));

다른 팁

일반적으로 :

당신이 비를 통과하는 경우const 참조, 발신자는 반복자가 수정되었는지 알 수 없습니다.

당신은 통과 할 수 있습니다 const 참조이지만 일반적으로 반복자는 충분히 작습니다.

귀하의 경우 :

반복자 사용과 관련하여 너무 표준적인 것이 아니라는 점을 제외하고는 당신이하는 일에 아무런 문제가 있다고 생각하지 않습니다.

그들이 "참조로 통과하지 말라"고 말할 때 아마도 두 번째 매개 변수에 대해 반복자를 값 매개 변수로 전달하는 것이 더 정상/관용적이기 때문일 수 있습니다.

그러나이 예에서는 두 가지 값을 반환해야합니다 : 구문 분석 된 int 값과 새/수정 된 반복자 값; 그리고 함수에 두 개의 반환 코드를 가질 수 없기 때문에 반환 코드 중 하나를 코딩하지 않으면 IMO 정상입니다.

대안은 다음과 같이 코딩하는 것입니다.

//Comment: the return code is a pair of values, i.e. the parsed int and etc ...
pair<int, input_iterator> parse(input_iterator start, input_iterator end)
{
}

제 생각에는, 당신이 이것을하고 싶다면 논쟁은 반복자에 대한 포인터가되어야합니다. 나는 통과 된 매개 변수가 변경 될 수 있다는 사실을 숨기기 때문에 비정상적인 참조 인수를 좋아하는 팬이 아닙니다. 나는 이것에 대한 나의 의견에 동의하지 않는 많은 C ++ 사용자가 있다는 것을 알고 있습니다. 괜찮습니다.

그러나이 경우에는입니다 그래서 반복자가 값 인수로 취급되는 것이 일반적입니다. 비정상적인 참조로 반복자를 통과하고 통과 된 반복자를 수정하는 것은 특히 나쁜 생각이라고 생각합니다. 그것은 단지 관용적 인 방식으로 반복자가 사용됩니다.

이 문제가없는 것을 할 수있는 좋은 방법이 있기 때문에 사용해야한다고 생각합니다.

template <typename input_iterator>
int parse_integer(input_iterator* begin, input_iterator end);

이제 발신자가해야 할 것입니다.

int i = parse_integer(&p, end);

그리고 반복자를 변경할 수 있음이 분명합니다.

그건 그렇고, 나는 또한 좋아합니다 Litb의 제안 새 반복기를 반환하고 구문 분석 된 값을 출력 반복기로 지정된 위치에 넣는 것.

이러한 맥락에서,내 생각을 전달 반복기에 참조로 완벽하게 현명한 한,그것은 잘 설명되어 있습니다.

점은 주목할 만한 가치가 있는 귀하의 접근 방식(전달 반복기를 참조에 의한 추적을 유지하의 어디에 있을 때 토큰화 스트림)은 정확하게 접근 방식에 의해 촬영 부스트::토.특히,의 정의를 참조하세요 TokenizerFunction 개념.전체적으로 높일::토 꽤 잘 설계하고 잘 생각했다.

표준 라이브러리 알고리즘은 반복자에게 독점적으로 값으로 반복자를 전달한다고 생각합니다 (누군가는 이제 명백한 예외를 게시 할 것입니다) - 이것은 아이디어의 기원 일 수 있습니다. 물론, 자신의 코드는 표준 라이브러리처럼 보인다고 말하는 것은 없습니다!

함수 선언의 두 번째 매개 변수가 참조가 누락 되었습니까?

어쨌든, 당신의 질문으로 돌아 가기 : 아니요, 나는 당신이 반복자를 참조로 전달해서는 안된다는 것을 읽지 않았습니다. 참조의 문제점은 참조 된 객체를 변경할 수 있다는 것입니다. 이 경우 반복자를 변경하려면 해당 지점을 넘어 전체 시퀀스를 망칠 가능성이 높아져 추가 처리가 불가능합니다.

단 하나의 제안 : 매개 변수를 조심스럽게 입력하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top