2017-09-30 5 views
7

C++의 ostream 클래스는 operator<<에 대한 많은 기본 오버로드를 제공하지만 모두 동일한 방식으로 정의되지는 않습니다.정적 대 멤버 연산자 오버로드 : std :: operator << 및 std :: ostream :: operator <<

namespace std { 
ostream &operator<<(ostream &os, char c); 
} 

산술 유형 streambuf 및 스트림 매니퓰레이터에 대한 overloads 있지만 부재로서 정의된다

overloadschar위한 유형 string 유형과 r- 수치 스트림은 같은 자유 namespace -scope 함수로 정의

namespace std { 
ostream &ostream::operator<<(int val); 
} 

내 질문

: 같은 std::ostream의 기능

이 구별의 이유가 있습니까? 이 연산자 오버로드에 대한 호출이 약간 다르게 작동합니다 (즉, 무료 namespace- 범위 정의에 대한 ADL). 최적화를 위해 특정 유형의 연산자 과부하가 선호 될 수 있다고 생각합니다. 그러나 여기 std::ostream은 다른 유형에 대해 두 유형의 정의를 모두 사용합니다. 이것이 의미하는이 구현 또는 구현 최적화에 이점이 있습니까?

답변

5

내가 최적화를 위해

음에 대한 연산자 오버로드의 특정 유형에 대한 선호가있을 수 있습니다 상상할 것, 아니. 하루가 끝날 때 둘 다 함수 호출로 수행됩니다. 해상도 자체를 과부하시키는 명백한 함의조차 없습니다. 표준은 [over.match]에 지시하기 때문에, 단락 26는 : 피연산자 클래스 또는 열거 타입을 갖는 경우

하는 사용자 정의 연산자 기능이 구현 선언 될 수도 연산자 또는 사용자 정의 변환은 피연산자를 내장 연산자에 적합한 유형으로 변환해야 할 수 있습니다. 이 경우 오버로드 확인은 연산자를 구현하기 위해 또는 내장 연산자를 호출 할 연산자 함수를 결정하는 데 사용됩니다.

과부하 해결을위한 후보 함수 집합은 구성원 후보, 비회원 후보 및 내장 된 후보의 조합입니다. 인수 목록에는 연산자의 피연산자가 모두 들어 있습니다. 후보 함수 세트에서 가장 좋은 함수는 [over.match.viable] 및 [over.match.best]에 따라 으로 선택됩니다.

이러한 연산자 오버로드는 모두 해결됩니다. 유일한 의미 차이점은 ostream에서 파생되는 클래스가 특정 멤버 과부하를 숨기기로 선택할 수 있다는 것입니다. 이는 파생 클래스에서 오버로드가 작동하는 방식에 따라 수행됩니다. 명시 적으로 선언 된 오버로드 만 적용됩니다. 이러한 멤버와 달리 자유 함수 오버로드는 ostream에서 파생되는 클래스에 대해서도 항상 과부하 해결에 참여합니다.

자유 함수 오버로드를 선택하려면 파생 클래스를 ostream&으로 변환해야하므로 자체 암시 적 변환 시퀀스의 순위를 지정해야합니다.모든 과부하가 자유로운 기능이라면 모호한 점이 발생할 수 있습니다.

그래서 우리는 항상 사용할 수있는 유용한 유형 (C 문자열과 개별 문자에 대한 포인터)에서 모호성 (포인터 및 산술 유형)을 야기 할 수있는 유형을 분리하는 것이 좋습니다. 그리고 그 모호성을 피하기 위해 "덜 유용"한 것들을 숨길 수 있습니다.


W.F. ostream은 실제로 basic_ostream<char>입니다. 무료 기능은 스트리밍 만 필요로하는 데이터에 적합합니다. 스트림의 문자 또는 문자열 기본 "알파벳". 따라서 basic_ostream<wchar_t>의 경우 해당 무료 함수는 wchar_twchar_t*을 수락합니다. 간단한 스트리밍에는 스트림 개인 섹션에 대한 액세스가 필요하지 않을 수도 있습니다.

다른 오버로드는 스트리밍하기 전에 직렬화가 필요한 데이터를위한 것입니다. 직렬화는 스트림 내부 상태와 밀접하게 결합되어 있기 때문에 이러한 오버로드를 멤버로 만드는 것이 훨씬 더 합리적입니다.

+0

"이러한 멤버와 달리 자유 함수 오버로드는 ostream에서 파생되는 클래스의 경우에도 항상 과부하 해결에 참여합니다. 그러나 ADL의보다 구체적인 범위에서 일치하는 다른 무료 함수를 사용하여 자유 함수를 숨길 수는 없습니다. –

+0

또한 'ostream'에서 파생 된 클래스의'ostream '에 대한 암시 적 변환이 자유 함수를 해결할 때 모호함을 만들 수 있는지에 대해 명확하지 않습니다. 죄송합니다! –

+1

@definecindyconst - 숨기지 않습니다. 단지 그들을 오버로드합니다. 회원은 [정말로 숨겨져 있지만] (https://ideone.com/d7XLZh). – StoryTeller