Pergunta

Eu tenho uma classe que definiu um operador definido pelo usuário para um tchar*, como assim

CMyClass::operator const TCHAR*() const
{
    // returns text as const TCHAR*
}

Eu quero ser capaz de fazer algo como

CMyClass myClass;
_tprintf(_T("%s"), myClass);

ou até

_tprintf(_T("%s"), CMyClass(value));

Mas ao tentar, o Printf sempre imprime (nulo) em vez do valor. Eu também tentei um operador normal de char*, bem como variações com const etc. ele só funciona corretamente se eu ligar explicitamente no operador ou fazer um elenco, como

_tprintf(_T("%s\n"), (const TCHAR*)myClass);
_tprintf(_T("%s\n"), myClass.operator const TCHAR *());

No entanto, eu não quero lançar. Como isso pode ser alcançado?

Observe que uma possibilidade é criar uma função que tenha um parâmetro de const TCHAR*, para que ele chama o operador TCHAR*, mas isso também não quero implementar.

Foi útil?

Solução

Evite operadores de conversão. Eles raramente fazem o que você quer e, em seguida, as chamadas explícitas são dolorosas. Renomear operator const TCHAR*() const para TCHAR *str() const.

Outras dicas

O padrão C ++ diz que conversões implícitas como essa não são aplicadas aos parâmetros de elipsis - como o compilador saberia qual a conversão para aplicar? Você terá que executar a conversão explicitamente você mesmo, ou melhor ainda para usar o printf.

Os operadores de conversão são chamados quando o compilador deseja converter um valor em outro tipo. Isso funciona para funções que obtêm parâmetros definidos de tipos específicos. Não funciona para funções variádicas como printf() com ... na declaração de função. Essas funções pegam os argumentos e depois trabalham com eles, para que o operador de conversão nunca seja chamado.

Para ser específico, quando o compilador vê printf("%s", foo), passa foo, seja o que for, para printf(), que terá que assumir que é adequado para um %s formato como é. Nenhum operador de conversão será chamado (embora certas promoções aritméticas ocorram).

Operadores de conversão em problemas gerais de causa. Ao ter esse operador nessa classe, você complicou a resolução de sobrecarga de função, pois o compilador pode interpretar um CMyClass Como se fosse um TCHAR *. Isso pode causar resultados inesperados, fazendo com que o código seja compilado quando você realmente não queria, ou selecionando a função sobrecarregada errada. (Por exemplo, dado CMyClass cmc;, a expressão cmc + 10 é de repente legal, já que TCHAR * + int é perfeitamente legítimo aritmético do ponteiro.) A prática usual é rotular essas conversões explicit.

O elenco é a coisa certa a fazer se você quiser usar as APIs do estilo PrintF e confiar em um operador de conversão (e não vou discutir aqui se você deve ou não usar esses recursos). No entanto, eu usaria elenco estático, por exemplo _tprintf(_T("%s\n"), static_cast<const TCHAR*>(myClass));

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top