2016-09-07 1 views
8

Peut-être que quelqu'un peut me l'expliquer:opérateur Condition ":" et LPCTSTR en-tête de la fonction

bool Func1(LPCTSTR sData) 
{ 
    if (sData) { ... } 
} 

Et j'ai appelé la fonction comme ceci:

CString str = _T(""); 
Func1((str.IsEmpty() ? NULL : str)); 

et fonction à l'intérieur 'sData' n'est jamais NULL, c'est toujours une chaîne vide mais pas NULL, pourquoi? Code Eddited comme ceci:

LPCTSTR strNull = NULL; 
Func1((str.IsEmpty() ? strNull : str)); 

Dans ce cas, il fonctionne correctement.

+0

'Func1 ((str.IsEmpty()? NULL: str));' ne compile pas sur VS2015, j'obtiens 'Erreur C2446 ':': pas de conversion de 'CString' à 'int' \t ... ' –

Répondre

5

Ceci est dû à la nécessité de convertir les deux opérandes en un type commun.
(Le résultat ne peut pas avoir différents types selon que la condition est vraie ou non.)

Le premier paramètre est équivalent à

str.IsEmpty() ? CString(NULL) : str 

depuis NULL ne dispose pas d'un type que vous convertir un CString à.
Et CString(NULL) construit un CString vide.

Le second est équivalent à

str.IsEmpty() ? strNull : (LPCTSTR) str 

depuis CString est convertible en LPCTSTR mais pas l'inverse.

Inlining le casting,

str.IsEmpty() ? (LPCTSTR) NULL : str 

devrait donner le même effet que le second.

+0

Et je suis toujours confus comment le [CString] (https://msdn.microsoft.com/en-us/library/cws1zdt8.aspx) c'tor est résolu dans l'expression 'CString (NULL)'. Il y a plusieurs facteurs qui prennent des arguments de pointeur. Comment le compilateur en choisit-il un (et lequel est-il)? – IInspectable

+0

Je l'ai maintenant: Tous les c'tors prenant un seul argument sont 'explicit', sauf celui qui prend un' const XCHAR * '. – IInspectable

1

À première vue, j'imagine que

Func1((str.IsEmpty() ? (LPCTSTR)NULL : str)); 

fonctionnerait aussi, et si elle le fait, vous avez probablement un problème de coulée de type qui a été fixé par le

LPCTSTR strNull = NULL; 
mission

parce qu'il sera associer le type LPCTSTR à la valeur null lorsque strNull est appelée ultérieurement.

5

L'opérateur conditionnel convertit ses deuxième et troisième arguments en un type commun à tous les deux. Je ne connais pas les détails de CString, donc c'est juste une supposition, mais il semble que l'opérateur conditionnel convertit NULL en CString pour correspondre au type du troisième argument, et passe cela, à travers une conversion implicite en LPCTSTR, en la fonction.

+1

' CString' a un opérateur de conversion implicite ([CSimpleStringT :: operator PCXSTR] (https://msdn.microsoft.com/en-us/library/tk1z2hd9.aspx)). Je ne comprends toujours pas comment le constructeur [CStringT :: CStringT] (https://msdn.microsoft.com/en-us/library/cws1zdt8.aspx) est résolu. Il y en a plusieurs qui correspondent à un pointeur 'NULL'. – IInspectable