2009-09-07 2 views
4

에 대한 모든 호출을 #define printf을 사용하여 제거 할 수 있습니다. std::cout << x << endl;과 같은 디버그 인쇄물이 많이 있다면 어떻게 될까요? 전 처리기를 사용하여 단일 파일에서 cout << 문을 신속하게 끌 수 있습니까?전 처리기를 사용하여 std :: cout 코드 행을 취소하십시오.

IFDBG(cout << result << endl); 

그럼 당신은 정의 할 수 있습니다 매크로 따라 :이 같은 뭔가

답변

3

NullStream은 디버그 문을 제거하는 빠른 것을 찾고 있다면 좋은 해결책이 될 수 있습니다. 내가 디버깅을 위해 자신의 클래스를 만드는 것이 좋습니다 그러나 더 디버그 기능이 필요한 경우, 그 필요에 따라 확장 할 수 있습니다 :

class MyDebug 
{ 
    std::ostream & stream; 
    public: 
    MyDebug(std::ostream & s) : stream(s) {} 
#ifdef NDEBUG 
    template<typename T> 
    MyDebug & operator<<(T& item) 
    { 
     stream << item; 
     return *this; 
    } 
#else 
    template<typename T> 
    MyDebug & operator<<(T&) 
    { 
     return *this; 
    } 
#endif 
}; 

이것은 당신이 처음에 원하는 것을 할 수있는 간단한 설정하고, 플러스는 혜택을 추가했다 .. 당신은 디버그 수준 등으로 기능을 추가시키는의

업데이트 : 당신은뿐만 아니라 (ENDL) 조종을받을 것인지는 매니퓰레이터가 함수로 구현되어 이제 때문에, 당신은 추가 할 수 있습니다 :

MyDebug & operator<<(std::ostream & (*pf)(std::ostream&)) 
{ 
    stream << pf; 
    return *this; 
} 

그리고 모든 조작 유형 (모든 조작 유형에 대한 과부하 할 필요가 없습니다 그래서) : 그 또한 일반 함수 포인터를 받아 들일 것입니다 때문에

template<typename R, typename P> 
MyDebug & operator<<(R & (*pf)(P &)) 
{ 
    stream << pf; 
    return *this; 
} 

,이 마지막으로주의해야합니다.

+1

이 스트림에 endl을 전달하면 오류가 발생합니다. T & item은 endl을 허용하지 않습니다. 어떤 단서로도이 오버로드를 수행 할 수 있습니까? –

+1

조작원에 대한 답변이 업데이트되었습니다. –

+0

고맙습니다. –

3

대체 디버그 출력 문

#ifdef DEBUG 
# define IFDBG(x) x 
#else 
# define IFDBG(x) 
#endif 
+0

IFDBG (cout << foo (x, y) << std :: endl);와 같이 작동하지 않는 것처럼 보입니다. 콤마가 매크로를 깨뜨릴 것입니다. – MSalters

+1

아니요, 매크로는 괄호 안에있는 범위를 벗어날 수 있기 때문에 매크로를 깨뜨리지 않습니다. 그러나이 호출은 그것을 깨뜨릴 것이다 : IFDBG (cout << foo () << std :: endl); –

3

당신은 아마 새로운 스트림과 같은 클래스를 정의하는 전처리 해킹을 할 수 인스턴스 이름은 cerr이며 아무 것도 수행하지 않습니다. 정말로 운이 좋다면 컴파일러는 함수가 아무 것도하지 않고 호출을 최적화하여 operator<<()으로 호출합니다.

class NullStream 
{ 
public: 
    NullStream(); 

    NullStream& operator<<(const std::string& text) { return *this; } 
    // And operators for other types, too 
} 
static NullStream cerr; 

이 같은

무엇인가, 그것은 (훨씬) 더 나은 소스를 통해 이동 및 로깅을위한 적절한 지원을 추가 할 비록 꽤 해킹이다.

6

표준 원칙으로 로깅은 피해야합니다 - 로그 파일에 로깅하는 것이 훨씬 더 좋습니다. 그런 다음 표준 구성 도구를 사용하여 로그 수준을 변경하거나 모두 해제 할 수 있습니다.

그냥 내 $ 0.02 ..... 이미 말했다

9

"언 와인드"으로, 빠른 해결책은 아무것도 실시하지 않는 스트림입니다. 그 세 개의 토큰 시퀀스 이후

class NullStream { 
    public: 
    NullStream() { } 
    template<typename T> NullStream& operator<<(T const&) { return *this; } 
}; 

당신은 여전히 ​​std::cout에 약간의 문제가, 그리고 당신이 정말로 개별적으로 std 또는 cout를 재정의하고 싶지 않은 :이 더 나은 구현은 생각입니다. 간단한 해결책은

#ifdef NDEBUG 
    #define COUT std::cout 
#else 
    #define COUT NullStream() 
#endif 

COUT << "Hello, world" << std::endl; 
0

cout을 대체하는 매크로를 정의하는 것은 VCS에 업로드해야하는 것이 아니지만 디버깅하는 동안 일시적으로 수행하는 경우 그 위치를 제공한다고 생각합니다. 그래서 그냥

#ifdef NDEBUG 
#define cout ostream(0).flush() 
#endif 

처럼 ostream(0)으로이 방법을 cout을 대체 할 수 있습니다, 그것은 모두 std::cout 및 일반 cout으로 작동하고, <iostream>을 포함 할 때 ostream 사용할 수 있습니다. ostream(0)에 글쓰기는 no-op입니다. flush 함수 호출은 비 const 참조를 얻을 수 있도록 수행되므로 std::string 및 기타 출력에 사용되는 비회원 operator<<에도 바인딩됩니다. 유형이 ostream이므로 정확히 cout과 같아야합니다.

3

이 매크로 정의 :

#ifdef DEBUG 
    #define MY_LOG std::cout 
#else 
    #define MY_LOG if(false) std::cout 
#endif 

이 매크로 장점은 컴파일러 최적화에를

그 IF를 내부에 위치 표현 일정 및 편집시 측정 할 수있는 경우에, 당신은 할 수있다 컴파일러가 이미 코드에서 코드를 제거했다는 것을 거의 확신합니다 ... https://stackoverflow.com/a/14657645/5052296

관련 문제