2013-04-21 2 views
2

저는 스트림 연산자를 사용하는 로깅 클래스를 구현하고 있습니다. 기본 개념은 사용자 지정 유형이 operator<<을 구현하여 로깅을 위해 읽을 수있는 표현을 제공 할 수 있다는 것입니다. 로깅 클래스는 다양한 메시지를 '수집'하여 파괴시 단일 로깅 항목으로 syslog 또는 기타로 전달합니다.연산자 << std :: stringstream에 대한 과부하 (just) :: 클래스를 외면했습니다

log_stream() << custom_type_variable; // no known conversion from 'log_stream' 
             // to 'basic_ostream<char, ...>& 
             // for 1st argument 

을 그리고 log_stream이기 때문에 지금은 왜 궁금해 :이 문은 표준 : : ostream에의 과부하로 시작하지 않고 사용자 정의가 대신 직접 입력하는 경우를 제외하고 아주 잘 실제로 작동

class log_stream : public std::ostringstream 
{ 
    inline ~log_stream() 
    { 
     forward_to_log(str().c_str()); 
    } 
}; 

class custom_type 
{ 
}; 

std::ostream &operator<<(std::ostream &stream, const custom_type &) 
{ 
    stream << "<custom_type data>"; 
    return stream; 
} 

log_stream() << "error in custom type: " << custom_type_variable; 

-a ostringstream은 -입니다. -입니다. 어떤 아이디어?

또한

(- log_stream 함께 사용 - 예를 들어 디스크에 직렬화 - fstream 사용할 경우에 하나의 기록을위한 두 가지 과부하 원) std::ostream 직접하지 log_stream& 대한 operator<< 과부하를 제공 할 수있는 방법이 ? 에 '할 r 값'operator<< 첫 번째 문제를 추가하면

EDIT # 1

가 해결된다. 지금/여전히 기본 클래스로 타입 변환에 나누기 그러나

template <typename Type> inline log_stream &operator<<(log_stream &&stream, Type&& type) 
{ 
    return operator<<(stream, std::forward<Type>(type)); 
} 

(이것은 ostringstream 또는 ostream 수).

log_stream() << custom_type(); // OK 
log_stream() << custom_type() << "text"; // OK 

log_stream() << "next"; // non-const lvalue reference to type 'log_stream' cannot bind 
         // to a value of unrelated type 'basic_ostream<char, ...>' 

basic_ostream<char, ...> 유형과 관련없는 이유는 무엇입니까? 이고 기본 클래스는 log_stream이며 이어야합니다.이 기본 클래스에 대한 참조는 여기에 있어야합니다. 그렇지 않아야합니까?

편집 # 2

글쎄, 그것은 물론 작동하게 회원 operator<<를 호출해야합니다.

template <typename Type> inline log_stream &operator<<(log_stream &&stream, Type&& type) 
{ 
    stream << std::forward<Type>(type); 
    return stream; 
} 

그래서 문제는 C++ (11)에 대한 해결 -하지만 여전히 C++ 03 (아아) 작동하지 않습니다.

염두에 두는 하나의 솔루션은 가장 가치가 낮은 형식의 변환 연산자 인 r 값을 operator()에 제공하는 것입니다.

class log_stream 
{ 
    inline log_stream &()() 
    { 
     return *this; 
    } 
} 

log_stream()() << custom_type() << "text"; 

귀엽지 만, 뭔가. 더 좋은 (더 예쁜) 아이디어? 삽입 사업자가 const가 아닌 참조을 필요로한다

+0

'streambuf'에서 파생해야하며 스트림 유형이 아닙니다. http://gabisoft.free.fr/articles/fltrsbf1.html – aschepler

+1

읽기 실제 문제에는 영향을 미치지 않습니다. –

+0

광고 추가 (편집) 질문 :'stream << type'의 반환 유형은'basic_ostream'이므로 파생 된 유형으로'static_cast'를 다시 수행해야합니다. 마찬가지로 : return static_cast (stream << std :: forward (type)); ' – dyp

답변

2

로그 스트림은 일시적으로입니다. 당신은 전자를 후자로 변환 할 수 없습니다.

log_stream 유형의 실제 명명 된 변수를 도입하고이를 <<의 왼쪽 피연산자로 사용해야합니다.

+0

왜 const 참조가되어야합니까? 임시는 유효하며 세미콜론까지 수정할 수 있습니다. 그러나 문제는 실제로 그것이 r 값이라는 것입니다 (연산자 << overload는 l 값이 필요합니다). 그러나 그것이 범위를 벗어날 때까지는 파괴되지 않는 것처럼 이름을주고 싶지 않습니다. –

+0

@ T.Carter : 임시 (평가 기준)가 실제로 수정할 수 있습니다. 그것에 대한 비 const 멤버 함수를 호출하십시오. 그럼에도 불구하고 당신은 그것을 const가 아닌 참조로 변환 할 수 없다. 그런 삶입니다. –

+0

좋아. 초기 게시물에서 ** EDIT # 1 **를 참조하십시오. –