2010-10-21 14 views
3

Quelqu'un peut-il s'il vous plaît expliquer pourquoi ce qui suit compilerapourquoi ne pas compiler en utilisant std :: max et C++/CLI?

int a = aAssignments[i]->Count; 
int b = fInstanceData->NumRequiredEmpsPerJob[i]; 
fInstanceData->NumSlotsPerJob[i] = max(a,b); 

mais

fInstanceData->NumSlotsPerJob[i] = max((int)(aAssignments[i]->Count), (int)(fInstanceData->NumRequiredEmpsPerJob[i])); //why on earth does this not work? 

coutume? L'erreur qu'il donne est error C2665: 'std::max' : none of the 7 overloads could convert all the argument types

La aAssigmments variables est de type array<List<int>^>^ et fInstanceData->NumRequiredEmpsPerJob est de type array<int>^

Le manuel std::max indique qu'il prend des valeurs par référence, il est donc clairement fait implicitement dans le premier exemple, alors pourquoi le compilateur ne peut-il pas faire la même chose pour les valeurs entières renvoyées par la propriété count, comme dans le second exemple? Puis-je obtenir une référence à un int explicitement?

+0

Comment peut-il même compiler cette propriété 'Count', les tableaux ont une propriété' Length'. – leppie

+1

@leppie C'est un tableau de listes, j'indexe le tableau à 'i' et je compte les éléments de cette liste. –

+0

Ah oui :) J'ai raté ça. – leppie

Répondre

2

(int)(aAssignments[i]->Count) appelle la propriété getter. Mais il évalue à une variable temporaire (rvalue) qui ne peut pas se lier à une référence non-const.

Selon ma documentation sur std::max, les paramètres devraient être des références const et tout devrait fonctionner. Que se passe-t-il si vous spécifiez explicitement le paramètre de type de modèle, par ex.

max<int>((int)(aAssignments[i]->Count), (int)(fInstanceData->NumRequiredEmpsPerJob[i]))

?

Qu'en est-il de max<int>(a + 0, b + 0)?

+0

Si je spécifie explicitement le type de template, il accepte le premier argument 'aAssignments [i] -> Count' mais pas le second argument, en me donnant un' ne peut pas convertir le paramètre 2 de 'int' à l'erreur 'const int &' '. Ajouter zéro à cet argument fonctionne bien! * Mais il doit y avoir un meilleur moyen ... * –

+1

Qu'est-ce qui se passe est ceci: Le deuxième argument décrit déjà une lvalue de type 'int', de sorte que le compilateur supprime la distribution (je crois à tort). Puisque le lvalue est sur le tas géré, il est sujet à être déplacé par le GC et a besoin d'une référence gérée ('int%') au lieu de la référence C++ ('int &'). La valeur doit être copiée dans un temporaire, qui n'est pas sur le tas géré, donc il se lie très bien, et la distribution aurait dû faire cela. Ressemble à un bogue de compilateur. –

+0

Il s'agit d'un bogue du compilateur qui affecte aussi le C++ natif. Va poster un lien de rapport de bug momentanément. –

1

Liste <> .Count n'est pas un champ, c'est une propriété. Vous ne pouvez pas créer une référence non gérée à une propriété gérée, l'obtention de la valeur de la propriété nécessite l'appel de l'accesseur de propriété. Court de votre première approche, la meilleure souricière ici est d'utiliser Math :: Max().

+0

Ceci est un vrai bug du compilateur –