이전 C/C++ 응용 프로그램의 디버그 매크로를 정리하는 동안이 문제가 발생했습니다. ostrstream
에서 상속 한 Tracer 클래스가 있습니다. C++ 98 이후로 더 이상 사용되지 않지만 응용 프로그램은 1998 년에 기록 된) 우리는 다음과 같이 사용하는!ostrstream는 상수 문자열을 포인터로 해석합니다.
Tracer() << "some" << " message" << " here";
이제 체인의 첫 번째 값은 위와 같이 상수 문자열, 소멸자에서 수행하는 (트레이서에 ostrstream::str()
를 호출 한 결과 인 경우 결과를 대기열에 삽입)에는 텍스트 대신이 문자열에 대한 포인터의 16 진수 표현이 포함됩니다. 따라서 위의 진술은 "0x401a37 message here"
과 같은 것을 얻을 것입니다. 이전 매크로에서는 항상 제거 된 첫 번째 값으로 long (스레드 ID)을 사용 했으므로 이런 현상은 발생하지 않았습니다.
gdb를 사용하여 첫 번째 삽입시에는 operator<<(void const*)
이 ostrstream에 호출되고 후속 삽입은 operator<< <...>(basic_ostream<...>&, char const*)
(가독성을 위해 제거 된 템플릿)이 호출됩니다.
누군가가이 동작을 설명 할 수 있습니까? 이 문제를 해결할 수있는 방법은 무엇입니까? 나는 쉬운 해결책을 발견했다. 이것은 첫 번째 인수로 << left
을 사용하고있다. 이것은 안전한가요? 이 작업을 수행하는 더 좋은 방법이 있습니까? 인수 const char*
얻어 operator<<
비 멤버 함수임을 모든 노트
#include <strstream>
#include <iostream>
using namespace std;
class Trace : public ostrstream {
public:
Trace();
virtual ~Trace();
};
Trace::Trace() : ostrstream() {}
Trace::~Trace() {
static_cast< ostrstream& >(*this) <<ends;
char * text = ostrstream::str();
cout << "MESSAGE: "<< text <<endl;
delete[] text;
}
int main(){
Trace() << "some" << " text" << " here";
Trace() << left << "some" << " text" << " here";
Trace() << 123 << " text" << " here";
}
설명 주셔서 감사합니다 - 내 의견을 nawaz '대답을 참조하십시오 무엇이 최선의 해결 방법이 될 것이라고? – l4mpi
아니요, 표준 방법은 'Tracer() << flush'와 같은 작업을 수행하여 스트림에 대한 좌변 값 참조를 얻는 것입니다. 그리고 만약 rvalue를 지원하는 최신 컴파일러가 있다면 어쨌든 작동 할 것입니다. 이 문제는 C++ 11 개정판에서 수정되었습니다. –
알겠습니다. 고마워요. 문제의 컴파일러는 g ++ 4.1.2 RedHat입니다. 슬프게도 C++ 11을 준수하지 않습니다 ... – l4mpi