Déclaration de problème: strong> ITERE sur un tableau d'objets et vérifiez si l'objet existe dans un ONUORDED_SET. problème: strong> Unorded_set Recherche ne fonctionne pas comme prévu ou j'ai eu le concept faux! p> Main: strong> p> surcharge de classe de bloc: strong> p> #pragma once
#include <string>
#include <memory>
using std::string;
class Block {
private:
string mName;
string mLib;
public:
Block(string const& name, string const& lib);
string getName() const;
string getLib() const;
bool operator==(std::unique_ptr<Block>& block) const;
};
3 Réponses :
Un Je ne suggérerais pas d'essayer de changer le comportement de Unommked_set code> nécessite une fonction de hachage et une fonction de comparaison. Vous utilisez les fonctions de hachage et de comparaison existantes pour
std :: unique_ptr code>, ce qui n'est certainement pas ce que vous voulez. P>
std :: unique_ptr
bloc code> et transmettez des personnalisés sur le constructeur du
non ordonnée_sed_sed code>. P>.
Merci. J'ai compris le problème. Tout commentaire sur la partie de but?
J'éviterais juste std :: vecteur code> sauf si vous pouvez la taille de bonne forme avant toutes les insertions (avec
réserve code>). Sinon, utilisez
std :: list code>.
D'accord. Merci David.
Vous essayez de comparer les pointeurs, pas les valeurs.
Vous devez spécifier la fonction de hachage pour la classe Par exemple, si vous souhaitez utiliser MNAME comme clé, le code sera le suivant: p> bloquer code>.
class Block {
private:
string mName;
string mLib;
public:
Block(string const& name, string const& lib)
{
mName = name;
mLib = lib;
}
string getName() const {
return mName;
};
string getLib() const {
return mLib;
}
bool operator==(const Block & block) const;
};
template<> struct std::hash<Block> {
std::size_t operator()(const Block & block) const noexcept {
return std::hash<std::string>{}(block.getName());
}
};
bool Block::operator==(const Block & block) const {
return block.getName() == mName;
}
int main() {
std::vector<Block> vertices;
vertices.emplace_back(Block("mod1", "work"));
vertices.emplace_back(Block("mod2", "work"));
vertices.emplace_back(Block("mod3", "work"));
std::unordered_set<Block> undefs;
undefs.emplace(Block("mod1", "work"));
undefs.emplace(Block("mod2", "work"));
for (auto& vertex : vertices) {
auto search = undefs.find(vertex);
if (search != undefs.end()) {
std::cout << "Block: " << vertex.getName() << "\n";
}
}
}
Merci. J'ai compris le problème. Ma seule préoccupation consiste à stocker des objets directement par rapport à la conservation des pointeurs qui leur dirigent. Comme je l'ai expliqué dans le but, je traite un grand nombre d'objets ici et la performance est ma priorité principale.
@Sourab Sharma, si la performance est importante, je vous suggère d'utiliser hachage en interne: vous pouvez calculer le hachage pour le MNAME (par exemple) et l'utiliser comme une clé de votre objet. Si vous allez opérer principalement avec ces hachages et non les noms, ce sera beaucoup plus rapide que les cordes de hachage à chaque fois. Ceci est parfois appelé "inlinage à cordes", mais parfois cela signifie des arbres préfixaux, pas de hachage. Pour la plupart des cas, le hachage est optimal, surtout si vous n'avez pas de collision
WHOOPS, je veux dire "string interne", pas d'inlinage :) Je vous recommande également de lire le livre "Architecture du moteur de jeu" qui décrit de nombreuses optimisations de ce type en termes de performances.
Je pense que j'ai maintenant assez de choses pour essayer de travailler avec. Merci encore. Et je vais vérifier le livre aussi.
Le problème est que vous essayez de comparer les pointeurs, qui sont différents! Je sauverais les raisons de l'utilisation de l'unique_ptr <> mais en faisant que vous essayez réellement de comparer des identités, au lieu d'états qui sont ce que vous voulez. P>
Vous pouvez donc voir ce que je veux dire, disons que le premier objet de bloc est en position 100 dans votre mémoire. Ce serait son identité. Nous avons donc des objets1 dont l'état est "mod1, travail" et dont l'identité est 100. Nous avons l'objet2, dont l'identité est de 150 mais son état est identique à l'objet1, "mod1, travail". P>
Tout ce que vous avez à la fois à l'intérieur du vecteur et que les pointeurs sont des pointeurs, vous avez donc des positions de mémoire. Lorsque vous les insérez dans le vecteur, vous avez inséré, disons, positionnez 100. Mais dans le non-ordonné vous inséré 150. Ils ont le même état, mais la méthode de recherche est à la recherche d'une position de mémoire. P>
J'espère que ma réponse a été utile. Si vous trouvez des erreurs ici ou pensez différemment s'il vous plaît faites le moi savoir. Bonne chance! :) p>
J'ai compris votre point (très empathétiquement expliqué, merci) mais si je dois créer des millions d'objets sur la pile et les stocker dans un conteneur, ce ne sera-t-il pas un problème par rapport à la conservation des pointeurs?
@Sourabsharma une pile construite sur std :: Liste CODE> stocke les pointeurs des objets déjà. Il suffit de ne pas construire sur
std :: vecteur code>.
@Sourabsharma Qu'entendez-vous sur la pile? Si vous utilisez std :: vecteur code> / Toute autre données de conteneurs est en cours d'enregistrement sur le tas en utilisant
Nouveau code> interne (pour être précis, ceci est défini par allocator). Il est très peu susceptible de vouloir stocker des millions d'objets sur la pile. Habituellement, la pile ne dépasse pas 10 Mo.
@espkk ok je n'étais pas au courant de cela.
quel est le problème? Qu'avez-vous obtenu en tant que sortie? Qu'est-ce que vous attendiez?
S'il vous plaît être si gentille de nous montrer ce que
block code> est et quel type de message d'erreur vous donne le compilateur.
Const comme un argument? Comme dans
Bool Block :: opérateur == (const std :: unique_ptr & block) const { code>
Je n'ai reçu aucun message d'erreur et le code compilé correctement. Mais quand j'ai couru, je n'ai reçu aucune sortie.
Vous bloquez la surcharge de la classe
Opérateur == code> n'a pas d'importance, car les objets du vecteur et de l'ONUNERDED_SET sont des pointeurs intelligents. Le code comparait les pointeurs intelligents, pas les objets de blocs.
Vous comparez des pointeurs avec des pointeurs qui appartiennent à des adresses.
Block CODE> JAMAIS ENTRÉE JAMAIS JEURE ICI SO
Bloc :: Opérateur == code> n'est pas considéré. Et puisque
Recherche code> ne prend que
unique_ptr code> SO Il ne peut pas être fait pour fonctionner comme vous le souhaitez. Utilisez
std :: recherche_if code> à la place.
Tout le monde peut bloquer-> getname () être appelé sur
std :: unique_ptr & block code> qui est la valeur non Const?
@RIXMENT • Les méthodes constantes peuvent être appelées des objets non constitutifs. Mais pas vice versa: Impossible d'appeler une méthode de non-Const sur un objet Const.
Lorsque vous définissez l'opérateur surchargé sous forme de méthode, il sera utilisé uniquement lorsque l'objet de cette classe sur le côté gauche, et non le pointeur non intelligent. Vous avez besoin d'une fonction autonome qui accepte 2 instances de
std :: unique_ptr code>
Quelle est la solution alors? Global
opérateur == (std :: unique_ptr &, std :: unique_ptr &) code>? Ou
opérateur == (bloc et, bloc et) code> suffira avec une conversion implicite de
std :: unique_ptr code> à
bloc code>?
Ok, une question suivante: trouvera-t-il un impact sur la performance / la complexité si mon upommande_set contient un million d'objets? [En outre, j'apprécie vraiment tous les commentaires, merci.]
@Sourabshama, peu importe la façon dont vous faites cela, vous devrez inspecter la valeur que vos indicateurs pointent. Cela sera probablement un peu plus lent que de comparer des adresses, mais c'est nécessaire. Que ce soit via
Find_IF code> ou un autre schéma ne fera pas une grande différence. Donc, ce n'est pas
wind_if code> qui aura intrinsèquement la performance touchée.
Je viens d'ajouter l'objectif. Tout commentaire de @all à ce sujet. Merci