0

現在、ログ ライブラリにいくつかの機能を追加しています。これらの 1 つは、そのクラス内から書き込まれるすべてのログ メッセージに自動的に付加されるクラスのモジュール名を宣言する可能性です。ただし、モジュール名が指定されていない場合は、先頭に何も追加されません。現在、名前を返す静的関数を持つ特性クラスを使用しています。

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

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

このクラスは、ヘルパー マクロを使用して定義できます。欠点は、モジュール名をクラスの外で宣言する必要があることです。クラス内でできるようにしてほしい。また、プリプロセッサ ディレクティブを使用してすべてのロギング コードを削除できるようにしたいと考えています。SFINAE を使用すると、テンプレート引数に特定のメンバーが含まれているかどうかを確認できますが、テンプレートに慣れていない他の人がコードを維持する必要があるため、より簡単なソリューションを探しています。何もない場合は、特性アプローチに固執します。

前もって感謝します!

4

2 に答える 2

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; }
};
于 2010-03-25T11:29:55.490 に答える
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;
    }
};
于 2010-03-25T11:35:48.300 に答える