2016-09-28 2 views
2

std::basic_string::substr 메서드는 pos, count 인수를 가지며 [pos, pos + count + 1]에있는 요소의 논리 범위를 지정합니다.입니다. 반대로, 표준 라이브러리의 대부분의 기능 (예를 들어, std::for_each)는 일부 혼란, 는 [시작 범위, 끝)std :: basic_string :: substr이 [시작, 종료] 규칙을 따르지 않는 이유는 무엇입니까?

이 다음 예외가 될 것으로 보인다 지정, begin, end와 유사한 형태의 인수를 (here, here, herehere을 참조하십시오). 왜 여기에 일반적인 범위 협약이 사용되지 않았습니까? 또한 std::vector::erase, 다른 랜덤 액세스 컨테이너의 메서드 인 을 수행한다는 점에 유의하십시오.

+2

contrustor를 사용하여 동일한 동작을 얻을 수 있습니다. 예 : 'std :: string substring {text.begin(), text.end()}'. 'substr'에 왜 그런 과부하가 없는지 모르겠다. – Zereges

+0

@Zereges : 중복되어 있기 때문입니다. 하위 문자열을 나타내는 두 개의 반복자가있는 경우,'std :: string :: string()'에 전달할 수있는 이유는 그것들을'std :: string :: substr()'오버로드에 전달해야하는 이유입니다. – MSalters

+0

@MSalters STL에는 많은 중복 오버로드 또는 기능이 있습니다. STL은 최소한으로 설계되지 않았습니다. – Zereges

답변

5

역사적인 이유. 표준 라이브러리에는 여러 개의 원본이 있으며, 그 중 하나는 STL입니다. 그것은 begin,end 대회를 가져 왔습니다. std::string은 STL의 표준 라이브러리에 합병되기 전이고 .substr(pos,length)을 사용하는 많은 기존 코드가있었습니다.

+0

... 그리고 지금 라이브러리를 디자인한다면'std :: string'은 매우 다르게 보일 것입니다. –

5

간단한 추측 :

서로 다른 방법을 일부 사용 반복자 및 기타하지 않는 이유는 아마도 다른 행동을 가지고 인용.

std::for_each은 일반적입니다. 모든 컨테이너 (심지어 원시 배열)에서 작동하는 일반 버전의 메서드를 사용하는 가장 쉬운 방법은 반복기를 사용하는 것입니다.

std::vector::eraseSequenceContainer 개념의 일부입니다, 그래서 (당신이 std::list? 아니면 std::set에 대해 poscountstd::vector에 대한,하지만 사용할 수 컨테이너의 모든 종류의 작업을 할 수있는 "일반적인"형식이 있어야합니다?). std::...::erase 어떤 SequenceContainer 잘 정의이기 때문에

template <typename C> 
void real_remove(C &c, const typename C::value_type &value) { 
    c.erase(std::remove(c.begin(), c.end(), value), c.end()); 
} 

이 유일한 작품 : 같은 개념을 갖는 것은 일반적인 코드를 만들 때 유용합니다. 한편

std::basic_string::substr 당신이 여기 반복자로 어떻게 할 것인지 ( std::vector의 일부 std::list입니다 ... erase 달리)과 std::basic_string 1 (안 반복자를 반환 std::basic_string의 일부분이다 ?).

insert 등등 size_type, append, 그리고에 과부하를 가지고, std::basic_string 다른 "제네릭이 아닌"(즉, 몇 가지 개념에 의해 필수가 아닌)을 방법, find 방법 중 일반적으로 온 가족이 있습니다. 주관적인보기에

, 나는 없기 때문에 다른 컨테이너처럼 행동하지 않는 std::basic_string을 가지고 더 좋은 생각 (I 표준이 SequenceContainer 또는 아무것도 모두로 std::basic_string 필요하다는 것을 확실하지 않다). 새 std::basic_string을 원하기 때문에 당신이 방법은 반복자를 복용하지만 객체를 반환 할 것이다, 그래서

1 당신은 내가 pos/count 대신 first하는 것보다이 훨씬 더 혼란을 찾을 것입니다 ... 여기 반복자를 반환 할 수 없습니다/last.

1

내가 왜 거기에 없었는지 말할 수 없었지만 놓친 [시작, 끝] 규칙을위한 범위 생성자가 있습니다.

template< class InputIt > 
basic_string(InputIt first, InputIt last, 
       const Allocator& alloc = Allocator()); 
관련 문제