distinguindo entre estático e métodos não-estáticos em c ++ em tempo de compilação?
-
10-07-2019 - |
Pergunta
Para alguns automação de rastreamento para casos de identificação Eu quero chamar qualquer um:
- um método não-estático do objeto contendo retornando seu identificador
- outra coisa que retorna sempre o mesmo id
Minha solução atual é ter uma classe base com um método que () e uma função global que (), que deve ser usado se não no contexto de um objeto. Este, porém, não funciona para funções de membro estático, aqui o compilador prefere o método não-estático sobre o global.
Exemplo simplificado:
class IdentBase
{
public:
Ident(const std::string& id) _id(id) {}
const std::string& which() const { return _id; }
private:
const std::string _id;
};
const std::string& which() { static const std::string s("bar"); return s; }
#define ident() std::cout << which() << std::endl
class Identifiable : public IdentBase
{
public:
Identifiable() : Ident("foo") {}
void works() { ident(); }
static void doesnt_work() { ident(); } // problem here
};
Posso alguma forma evitar o uso de soluções alternativas como uma macro especial para funções de membro estático (talvez usando alguma magia modelo)?
Solução
Você pode ser capaz de usar is_member_function_pointer da biblioteca TypeTraits impulso. sugestão de usar código diferente nos casos estáticos e não-estáticos da SBI é provavelmente melhor ainda.
Outras dicas
Defina um modelo função que retorna um identificador padrão para todos os tipos.
template<typename T>
const std::string& which(const T& object)
{ static const std::string s("bar"); return s; }
Especialize o modelo de função para a classe específica.
class IdentBase
{
public:
IdentBase(const std::string& id): _id(id) {}
const std::string& id() const { return _id; }
private:
const std::string _id;
};
template<>
const std::string& which(const IdentBase& object)
{ return object.id(); }
Chamar o modelo de função, passando uma instância que você deseja identificar.
int main()
{
int i;
std::cout << which(i) << std::endl;
IdentBase foo("foo");
std::cout << which(foo) << std::endl;
return 0;
}
Você precisa de um identificador diferente para cada instância de cada classe como no seu exemplo, ou você está apenas tentando identificar qual classe é no rastreamento?
Alterar função o que () e membro _id para estático iria expô-los tanto para suas funções de membro estático, e como um bônus diminuir o uso de memória.