Pregunta

Actualmente estoy añadiendo algunas características de nuestro tala-biblioteca. Una de ellas es la posibilidad de declarar un módulo de nombre para una clase que automáticamente se preprended a cualquier diario de los mensajes que escriben desde dentro de esa clase. Sin embargo, si no se proporciona ningún nombre-módulo, nada se antepone. Actualmente estoy usando una clase rasgo que tiene una función estática que devuelve el nombre.

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

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

Esta clase se puede definir utilizando un helper-macro. El inconveniente es que el nombre del módulo tiene que ser declarado fuera de la clase. Me gustaría que esto sea posible dentro de la clase. También, quiero ser capaz de eliminar todos los registros de código utilizando una directiva de preprocesador. Yo sé que el uso de SFINAE se puede comprobar si un argumento de plantilla tiene un cierto miembro, pero como otras personas, que no son tan amigable con plantillas como soy, tendrán que mantener el código, Busco a una solución mucho más simple. Si no la hay, voy a seguir con los rasgos aproximan.

Gracias de antemano!

¿Fue útil?

Solución

  

Me gustaría que esto sea posible dentro de la clase.

Esto no es posible con su enfoque, especializaciones explícitas deben ser declarados en el espacio de nombres de los que la plantilla es un miembro.

Usted no dice cómo las miradas reales utilizando un código como, pero debe ser capaz de dejar nombre y la resolución de la sobrecarga de trabajo para usted (por ejemplo, de una macro de registro):

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; }
};

Si desea definir name() sólo en clases y no fuera, no es, por supuesto, no hay necesidad de plantillas o sobrecargas:

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; }
};

Otros consejos

No estoy seguro de lo simple que la solución debe ser, aquí está una muy simple he usado un par de veces.

Hay una ClassName clase base con algo como:

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

Y otra clase heredaría, dándole su nombre:

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

    void func()
    {
         LOG << "Some log here" << endl;
    }
};
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top