6
votes

Taille_T: un opérateur? (et un moyen d'utiliser un usered_set)

Qu'est-ce que

error C2549: user-defined conversion cannot specify a return type


0 commentaires

5 Réponses :


1
votes

dans n'importe quelle classe foo , opérateur t () const est un opérateur de distribution qui vous permet de lancer foo à t : xxx

par exemple, un std :: fstream a un opérateur de Cast-to-Bool afin que vous puissiez l'utiliser dans expressions comme si (mystream) ... .


En réponse à votre besoin d'utiliser des conteneurs non ordonnés: vous devrez mettre en œuvre une fonction de hachage ou un objet de fonction, qui Correspond à la signature Taille_T (const foo &) . Si vous souhaitez le faire avec un impact le moins visible sur le code de l'utilisateur, Spécialiser std :: hash xxx

maintenant nous pouvons utiliser STD :: ONUODERED_SET directement, fourni FOO fournit opérateur == .


8 commentaires

Notez que ce qui précède fonctionne également s'il y a un T :: t (const foo &) défini.


@Node: Oui, soit que vous convertissez A en B ou que vous construisez B de A. Que se passe-t-il si les deux sont définis, cependant, le constructeur one-argument a priorité?


Pourquoi doit-il être converti en taille_t ?


@Dante: Que voulez-vous dire? Je réponds à deux questions, 1) Qu'est-ce qu'un opérateur de distribution et 2) Comment spécifier une fonction de hachage. Les deux sont des choses différentes. La fonction de hachage n'est qu'une fonction ordinaire (ou un foncteur) et non des opérateurs de moulage y sont utilisés.


@Kerrek SB, je sais, mon pourquoi est pour la raison Taille_T agit comme hachage.


@Dante: un type ne fait pas vraiment "agir" du tout - c'est juste un type intégré de la machine, universel, non signé non signé! Quel type de meilleur serait-il pour une valeur de hasch? Vous voulez que ce soit rapide et gros, c'est exactement le bon type.


@Kerrek - Je viens de l'essayer sur Ideone et on dirait que l'opérateur de conversion a priorité.


@Node: Sweet! Étrangement, il semble dépendre de la Constitution de l'opérateur de distribution: non-const , const . Notez également qu'il y a une différence entre b b b (a) et b b = a !



14
votes

C'est le opérateur de type . Fondamentalement prévoit de convertir implicitement l'objet au type spécifié, dans ce cas taille_t code>.

EDIT: stry> p>

Dites que vous avez une fonction définie comme indiqué suit: p> xxx pré>

si votre classe bord code> définit l'opérateur de type-couplage pour la conversion vers Taille_t code> Vous pouvez faire ce qui suit : P>

edge e;
Foo( e );


12 commentaires

Souhaitez-vous s'il vous plaît fournir plus de détails sur la façon dont cette conversion implicite fonctionne? Et pourquoi doit-il être converti en ze_t ?


@Dante n'est pas un geek: j'ai ajouté plus de détails.


I Modifier Opérateur Taille_t () Const à Taille_T to_Size_T () Const , mais cela ne fonctionne pas. Vos détails ajoutés signifient en général , je ne devrais pas écrire ce genre de conversion, non? Dans std :: TR1 :: Unommked_set , il semble exiger cela, et voici pourquoi j'ai demandé pourquoi. Il fonctionne comme hachage car il est converti en entier non signé (qui est taille_t )?


@Dante n'est pas un geek: oui, vous êtes absolument correct; J'ai de nouveau édité la réponse :-). En général, c'est une mauvaise idée, mais requise dans ce cas.


Désolé mais le dernier bit (peut-être ...): la manière habituelle d'inclure une fonction de hachage consiste à définir que dehors la classe elle-même?


@Dante n'est pas un geek: oui, vous pouvez le définir comme des foncteurs en dehors de la classe elle-même. Voici un exemple: Stackoverflow.com/Questtions/2099540/... . Une autre façon de le faire est de fournir des spécialisations de modèles pour std :: hash () et std :: égal_to pour votre type de classe.


@PRAETORIAN: ÊTES-VOUS SÛR D'UNE CONVERSION-TAILLE_T est automatiquement utilisée par std :: hash ? Je viens d'essayer cela et ça n'a pas fonctionné. Autant que je sache, vous devez spécialiser std :: hash manuellement, aucun moyen de cela - il n'y a pas de "je suis la fonction de hachage".


@Kerrek SB: Je pourrais me tromper, mais si vous spécifiez l'opérateur de type-CAST, puis transmettez votre classe en tant que paramètre de modèle de fonction de hachage optionnel sur ONUORDED_MAP ?


@Petorien: Comment est-ce censé travailler, Unorded_sed ? La classe de hachage doit être un "type appelable", et l'opérateur de distribution fait pas fournit ce comportement.


@Kerrek SB: Vous avez raison, la surcharge de l'opérateur de type ne fonctionne pas. Mais vous pouvez définir un appel d'appel de fonction qui prend une référence de const à votre objet, puis utilisez votre type de classe pour la fonction Hash. Faites de même pour la comparaison également et vous pouvez utiliser Unorded_set


@Pratorien: OK - vous pourrait le faire, mais vous obtiendrez un badge pour la plupart des conceptions contre-intuitives! (Et que si ces opérateurs sont déjà pris?) Le boeuf principal avec c'est que vous devez vous rappeler que vous devez vous rappeler que vous écrivez vos paramètres de conteneur, c'est pourquoi je préférerais généralement spécialiser std :: hash . Presque toujours, même s'il n'y a jamais besoin d'avoir plus d'une fonction de hachage pour un type ...


@Kerrek SB: Je suis d'accord, ce serait un design contre-intuitif (j'ai même suscité votre commentaire moi-même :-)). Quoi qu'il en soit, j'ai édité la réponse.



2
votes

Il s'agit d'un opérateur de conversion, comme indiqué par Erreur C2549: la conversion définie par l'utilisateur ne peut pas spécifier de type de retour . Il définit la manière dont votre type peut être converti en taille_t dans ce cas. En général, opérateur x () {...} Spécifie comment créer un x de votre type.


1 commentaires

Seriez-vous s'il vous plaît fournir plus de détails sur la façon dont cette conversion fonctionne? Et pourquoi doit-il être converti en ze_t ?



2
votes

7 commentaires

Souhaitez-vous s'il vous plaît fournir plus de détails sur la façon dont cette conversion implicite fonctionne? Et pourquoi doit-il être converti en ze_t ?


@Dante n'est pas un grec: je crois que le lien que j'ai fourni contient plusieurs exemples et une bonne explication. Non?


Le lien ne répond pas à la deuxième partie de la question.


@Dante: Nous n'avons pas assez d'informations à raconter à coup sûr, mais cela ressemble à l'approche de sondage douteuse de l'utilisation de Unorded_set que vous avez chooglé nécessite que les objets utilisent cet opérateur de conversion pour fournir leur hadrage code. Ceci est assez dangereux, car il arrête le compilateur d'attraper des erreurs telles que la typage int x = bord; lorsque vous voulez dire int x = bord.x; . Avec l'opérateur de conversion, cela affectera le hachage de l'edge à x . Comme vous le dites dans la question, l'approche habituelle est de définir un foncteur pour calculer le hachage.


@Mike Seymour, et le foncteur doit être défini quelque part en dehors de la classe?


@Dante: Il faut simplement être une fonction membre appelée gethash ()


@Dante: Je le définirais à l'extérieur de la classe, mais vous pourriez le nicher à l'intérieur si vous préférez. Ensuite, vous devez le spécifier lors de la déclaration de votre type de jeu: Unommked_sed . Sinon, vous pouvez peut-être la définir comme une spécialisation de std :: tr1 :: hash , alors vous n'aurez pas besoin de le spécifier comme un argument sur non ordonné_sed_sed .



1
votes

C'est un opérateur de conversion implicite. Il permet d'utiliser essentiellement un objet de votre classe d'être utilisé dans un contexte où un taille_t est attendu (appelant cet opérateur à faire la conversion).

Pour utiliser Unommked_set vous besoin avoir une sorte de fonction hashign. Dans ce cas, il est déguisé en tant que Taille de l'opérateur , que je ne recommande pas vraiment parce que c'est simplement obscurcissant le fait que c'est une fonction de hachage. Je voudrais juste aller de l'avant et définir une vraie fonction de hachage / agenceur et l'utiliser à la place. Ce sera plus clair et les futurs Mainteners vous remercieront.


1 commentaires

Je considère (ed) comme le meilleur moyen car tout peut être inclus dans la classe elle-même. Une vraie fonction de hash peut-elle être incluse dans la classe elle-même? Voulez-vous s'il vous plaît donner plus de détails sur le réel hachage?