std :: fstream 클래스가 std :: string을 사용하지 않는 이유는 무엇입니까?

StackOverflow https://stackoverflow.com/questions/32332

  •  09-06-2019
  •  | 
  •  

문제

이것은 디자인 문제는 아니지만 실제로는 그렇게 보일 수 있습니다.(글쎄요, 그것은 일종의 디자인 질문입니다).내가 궁금한 것은 C ++ std::fstream 클래스가 생성자 또는 open 메서드에서 std::string를 사용하지 않는 이유입니다.누구나 코드 예제를 좋아합니다. 라코 디스

파일로 작업 할 때 항상이 기능을 사용합니다.확실히 C ++ 라이브러리는 가능한 한 std::string를 사용합니까?

도움이 되었습니까?

해결책

C 문자열을 취함으로써 C ++ 03 std::fstream 클래스는 종속성을 줄였습니다. std::string 클래스에서. 그러나 C ++ 11에서 std::fstream 클래스는 생성자 매개 변수에 대한 std::string를 전달할 수 있습니다.

이제 왜 std:string에서 C 문자열로의 투명한 변환이 없는지 궁금 할 것입니다. 따라서 C 문자열을 예상하는 클래스는 std::string를 예상하는 클래스처럼 여전히 std::string를 사용할 수 있습니다. .

이로 인해 전환주기가 발생하여 문제가 발생할 수 있기 때문입니다. 예를 들어, std::stringstd::strings와 함께 fstreams를 사용할 수 있도록 C 문자열로 변환 될 수 있다고 가정합니다. 또한 C 문자열이 현재 표준의 상태와 같이 유전자 코드 태그 코드로 변환 될 수 있다고 가정합니다. 이제 다음을 고려하십시오. 라코 디스

std::string와 C 문자열 사이에서 어느 쪽이든 변환 할 수 있기 때문에 std::string에 대한 호출은 두 f() 대안 중 하나로 해석 될 수 있으므로 모호합니다. 해결책은 하나의 변환 방향을 명시 적으로 만들어 변환주기를 끊는 것입니다. STL은이를 f()로 수행하기로 선택했습니다.

다른 팁

C ++ 표준위원회가 표준 라이브러리에있는 시설 간의 상호 작용을 실제로 최적화하지 않은 곳이 있습니다.

std::string와 라이브러리에서의 사용은 다음 중 하나입니다.

다른 예는 std::swap입니다.많은 컨테이너에 스왑 멤버 함수가 있지만 std :: swap의 오버로드가 제공되지 않습니다.std::sort도 마찬가지입니다.

이 모든 사소한 문제가 다가오는 표준에서 수정되기를 바랍니다.

아마 위안 일 수 있습니다. 모든 fstream은 C ++ 0x 표준의 작업 초안에서 open (char const *, ...) 옆에 open (string const &, ...)을 얻었습니다. (예 : basic_ifstream 선언은 27.8.1.6 참조)

따라서 완성되고 구현되면 더 이상 얻을 수 없습니다. :)

스트림 IO 라이브러리는 STL 이전에 표준 C ++ 라이브러리에 추가되었습니다.이전 버전과의 호환성을 깨지 않기 위해 STL이 추가 될 때 IO 라이브러리를 수정하지 않기로 결정했습니다. 비록 그것이 당신이 제기 한 것과 같은 문제를 의미하더라도.

@ Bernard :
Monoliths "Unstrung.""All for one, one for all"은 총사에게는 효과가있을 수 있지만 클래스 디자이너에게는 거의 효과가 없습니다.여기에 완전히 모범적이지 않은 예가 있으며, 디자인이 과잉 디자인으로 변할 때 얼마나 잘못 될 수 있는지 보여줍니다.불행히도 예는 가까운 표준 라이브러리에서 가져온 것입니다. ~ http://www.gotw.ca/gotw/084.htm

<인용구>

사실이 아닙니다. std :: string의 인터페이스가 크다는 것은 무엇을 의미합니까? 이 맥락에서 large는 무엇을 의미합니까-많은 메서드 호출? 나는 우스꽝스럽지 않고 실제로 관심이 있습니다.

실제로 필요한 것보다 더 많은 메소드를 가지고 있으며, 반복자보다 적분 오프셋을 사용하는 동작은 약간 불확실합니다 (나머지 라이브러리가 작동하는 방식과 상반 됨).

제 생각에 진짜 문제는 C ++ 라이브러리가 세 부분으로 구성되어 있다는 것입니다. 이전 C 라이브러리가 있고 STL이 있으며 문자열 및 iostream이 있습니다. 여러 부분을 연결하기 위해 약간의 노력을 기울 였지만 (예 : C ++에서 오버로딩을 지원하기 때문에 C 라이브러리에 오버로드 추가, basic_string에 반복기 추가, iostream 반복기 어댑터 추가) 많은 불일치가 있습니다. 자세히보세요.

예를 들어 basic_string에는 표준 알고리즘의 불필요한 중복 메소드가 포함됩니다. 다양한 찾기 방법을 안전하게 제거 할 수 있습니다. 또 다른 예 : 로케일은 반복기 대신 원시 포인터를 사용합니다.

C ++는 오늘날 우리가 코드를 작성하는 괴물보다 더 작은 기계에서 자랐습니다.iostream이 처음이었을 때 많은 개발자들이 코드 크기에 관심을 가졌습니다 (전체 프로그램과 데이터를 수백 KB에 맞아야했습니다).따라서 많은 사람들이 "큰"C ++ 문자열 라이브러리를 가져오고 싶지 않았습니다.많은 사람들이 코드 크기와 같은 이유로 iostream 라이브러리를 사용하지 않았습니다.

오늘처럼 버릴 수있는 수천 메가 바이트의 RAM이 없었습니다.우리는 일반적으로 함수 수준 링크가 없었기 때문에 라이브러리 개발자가 많은 개별 개체 파일을 사용하거나 호출되지 않은 수많은 코드를 가져 오는 것이 었습니다.이 모든 FUD로 인해 개발자는 std :: string에서 벗어나게되었습니다.

그때 나는 std :: string도 피했습니다."너무 부풀어 오름", "너무 자주 malloc이라고 불림"등. 어리석게도 문자열에 스택 기반 버퍼를 사용한 다음 오버런이 발생하지 않도록 모든 종류의 지루한 코드를 추가합니다.

STL에 문자열을 사용하는 클래스가 있습니까? 그렇게 생각하지 않습니다 (빠른 검색에서 찾을 수 없음).따라서 STL의 어떤 클래스도 다른 STL 클래스에 종속되어서는 안된다는 디자인 결정일 것입니다 (기능에 직접 필요하지 않음).

나는 이것이 의존성을 피하기 위해 생각되고 수행되었다고 믿습니다.즉, #include 은 하나를 #include 으로 강제해서는 안됩니다.

솔직히이 문제는 상당히 사소한 문제인 것 같습니다.더 나은 질문은 std :: string의 인터페이스가 왜 그렇게 큰가요?

요즘에는이 문제를 매우 쉽게 해결할 수 있습니다. -std=c++11CFLAGS를 추가하세요.

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