2010-03-25 8 views
0

현재 로깅 라이브러리에 몇 가지 기능을 추가하고 있습니다. 이들 중 하나는 클래스 내에서 로그 메시지를 작성하기 위해 자동으로 미리 준비된 클래스의 모듈 이름을 선언 할 수있는 가능성입니다. 그러나 module-name이 제공되지 않으면 아무 것도 붙지 않습니다. 현재 이름을 반환하는 정적 함수가있는 trait-class를 사용하고 있습니다.로깅을위한 클래스의 모듈 이름을 선언하십시오.

template< class T > 
struct ModuleNameTrait { 
    static std::string Value() { return ""; } 
}; 

template< > 
struct ModuleNameTrait<Foo> { 
    static std::string Value() { return "Foo"; } 
}; 

이 클래스는 도우미 매크로를 사용하여 정의 할 수 있습니다. 단점은 모듈 이름을 클래스 외부에서 선언해야한다는 것입니다. 나는 이것이 수업 시간에 가능하기를 바란다. 또한 전 처리기 지시문을 사용하여 모든 로깅 코드를 제거 할 수 있기를 원합니다. SFINAE를 사용하면 템플릿 인수에 특정 멤버가 있는지 확인할 수 있지만 다른 사람들 (템플릿을 친숙하지 못함)으로 인해 코드를 유지 관리해야하므로 훨씬 간단한 솔루션을 찾고 있습니다. 아무도 없다면 나는 특성 접근법을 고수 할 것이다.

미리 감사드립니다.

답변

2

나는 이것을 수업 내에서 가능하게하고 싶습니다.

이 방법은 사용할 수 없으며 명시 적 전문화는 템플릿이 속한 네임 스페이스에 선언되어야합니다.

당신은 실제 사용하는 코드가 어떻게 보이는지 말을하지 않습니다,하지만 당신은 (예를 들어, 로깅 매크로에서) 당신을 위해 이름과 오버로드 확인 작업을 할 수 있어야한다 :

template<class T> const char* const name(const T&) { return ""; } 

class X; 
const char* const name(const X&) { return "X"; } 

struct X { 
    // prints "X" 
    void f() { std::cout << name(*this) << std::endl; } 
}; 

struct Y { 
    static const char* const name(const Y&) { return "Y"; }  
    // prints "Y" 
    void f() { std::cout << name(*this) << std::endl; } 
}; 

struct Z { 
    // prints "" 
    void f() { std::cout << name(*this) << std::endl; } 
}; 

당신이 원하는 경우 클래스 만에 name()을 정의하고 있지 외부 템플릿 또는 과부하가 필요 물론 없다 :

const char* const name() { return ""; } 

struct X { 
    static const char* const name() { return "X"; }  
    // prints "X" 
    void f() { std::cout << name() << std::endl; } 
}; 

struct Y { 
    // prints "" 
    void f() { std::cout << name() << std::endl; } 
}; 
+0

이 완벽! 때로는 나무 숲이 보이지 않는데, 나는 복잡하게 생각하고있었습니다. 고맙습니다! –

+0

나는 그 문제를 안다 : –

0

내가 솔루션이 될 방법을 간단하게 확실하지 않다가, 여기에 내가 몇 번 사용 아주 간단한 하나입니다.

처럼 뭔가 기본 클래스 ClassName 있습니다 :

class ClassName 
{ 
    string name; 
public: 
    ClassName(string strName = "") : name(strName) 
    { 
     if(strName.length()) 
       strName += ": "; 
    } 
    string getName() 
    { 
     return name; 
    } 
}; 
#ifdef _DEBUG 
    #define LOG cout << getName() 
#else 
    #define LOG cout 
#endif 

그리고 다른 클래스 이름을주고, 그것을 상속 것 :

class Session : virtual public ClassName 
{ 
public: 
    Session() : ClassName("Session") 
    { 
    } 

    void func() 
    { 
     LOG << "Some log here" << endl; 
    } 
}; 
+0

나는이 접근법을 또한 고려했다. 그러나 나는 그것을 정의 또는 전처리 지시어에 의해 쉽게 비활성화 될 수 없기 때문에 그것을 버렸다. –

+0

ifdef가 거의 없기 때문에 함수를 호출하지 않고 빈 클래스의 상속으로 모든 것을 제한 할 수 있습니다. –