2010-02-03 1 views
3

함수에 표준 : : ostream에 전달 :C++ - 나는 C++로 작은 디버그 인라인 함수의 생각

_debug(7, cout << "Something something" << someint << endl); 

: 이것은 내가 그것을 사용하고자하는 방법의 예입니다

void inline debug(int debug_level, ostream& out) { 
    if (debug_level <= verbosity) { 
     out.flush(); 
    } 
    else { 
     ostream tmp; 
     tmp << out; 
    } 
} 

그러나 그것은 내가 계획 한대로 작동하지 않습니다 - 자세한 수준이 높거나 같으면 디버그 수준을 함수에 전달할 때만 메시지를 인쇄하고 싶지만 디버그 수준에 관계없이 매번 인쇄되므로 데이터가 유지됩니다 cout 버퍼에. 지금까지는이 함수가 최근에 가지고있는 최선의 생각이 아니라고 생각하지만 여전히 cout, cerr 등과 관련된 버퍼를 지울 수있는 방법이 있는지 알고 싶습니다. 제대로 작동하는 데 이러한 종류의 함수를 사용할 수 있습니까?

+0

null 스트림의 아이디어를 사용하여 Konrad의 경로를 찾으려면 http://stackoverflow.com/questions/760301/implementing-a-no-op-stdostream –

+0

아,이 질문을 살펴보십시오. oldschool-C 매크로가 맘에 들지 않는다. 나는 C++ 방식을 선호한다.) – zbigh

+0

매크로는 C++ 에서처럼 피할 수있다. 두려운 것이다. –

답변

2

함수/템플릿으로 수행 할 수 있는지 확실하지 않습니다. 내가 매크로의 (로그 메시지 스트림이 분리되어)와 코드를 알고 :이 작동하지만 더 나은 솔루션에 관심이 있어요,

#define LOG(svrty, out, msg)\ 
do {\ 
    if (svrty >= debug_level) out << msg;\ 
} while(0) 

합니다. 구성 및 디버그 수준에서 로깅 할 위치를 결정하도록해야합니다.

2

기능 본문이 입력되기 전에 함수 매개 변수가 평가되므로 항상 메시지가 인쇄됩니다. 당신이 까다로운 경우

DOUT(42, cout << "The value is " << something); 

것은, 당신이 원하는 것 :

#define DOUT(level, expr) \ 
    if (level >= verbosity) {  \ 
     expr << endl;   \ 
    } 

사용에서 : 그들이 사용하는 경우 매크로 변수 만 평가 같이, 매크로와 당신이 원하는 내가 생각하는 효과를 얻을 수 있습니다 이것을 do/while 루프로 마무리하십시오 - 개인적으로, 그렇게하는 것을 결코 신경 쓰지 않습니다. 위, 또는이 같은

+0

@Neil : 글쎄, 이제는 사용법이 잘못되었으므로 정말 귀찮을 것입니다. 그 뒤에 여분의 세미콜론을 넣으십시오. 이것이 if 문 안에 있고 다음 문이 else 문이라면 어떻게되는지 생각하지 마십시오. –

+0

@Konrad Suprisingly 충분히, 나는 이것을 안다. 내 작은 약점 중 하나라고 생각해보십시오. –

6

어느 매크로를 사용 :

struct nullstream : ostream { 
    nullstream() : ostream(0) { } 
}; 

ostream& dout(int debug_level, ostream& out = cerr) { 
    static nullstream dummy; 
    return debug_level <= verbosity ? dummy : out; 
} 

// … 

dout(level) << "foo" << endl; 
dout(level, cout) << "IMPORTANT" << endl; 

(endl도 홍조를 유발하여, 필요 수동 세척 없습니다!)

+0

스트림 버퍼의 불필요한 생성 만 문제입니다.스트림 버퍼 생성을 피하는 것이 더 좋다. 로깅이 헤드리스 프로세스에서 다른 작업보다 더 자주하는 일이라고 생각하면됩니다. –

+0

@CodeMedic : 그 이유는 스트림이 '정적'인 이유입니다. 모든 프로그램에서 ** 한 번 ** 생성되었습니다. 이는 거의 오버 헤드가 없으므로 원하는만큼 자주이 메서드를 호출 할 수 있습니다. –

+0

@Konrad Rudolph : 멋지게 보이지만 더미에 상수 쓰기가되지 않아서 버퍼 오버 플로우가 발생합니다. – zbigh

0

디버그 수준 런타임 구성 가능합니까? 당신은 템플릿과 템플릿 특수화를 사용할 수
하지 않으면 : 당신은 아무것도 출력하지 않으려면

template <int DebugLevel, int Verbosity> 
ostream &debug(ostream &out); 

template<> 
ostream &debug<7, 5>(ostream &out) { /* do stuff */ } 

그런 식으로, 단지 콘라드 루돌프 같은 더미 ostream에 제안으로 돌아갑니다.