2017-02-28 2 views
1

J'ai essayé d'insérer un objet Movie dans le conteneur unordered_set<Movie>, mais j'ai reçu une erreur indiquant qu'il n'y a pas de fonction membre correspondante. Je l'ai fait quelque chose comme çaAucun membre correspondant à insérer sur unordered_set

void ActorGraph::addActor(string actor_name, string movie_title, int movie_year){ 
    unordered_map<string, unordered_set<ActorNode>>::iterator con_itr = connections.find(actor_name); 
    ActorNode actor(actor_name); 
    Movie movie(movie_title, movie_year); 

    if(con_itr != connections.end()){ 
     auto adjSet = con_itr->second; 
     unordered_set<ActorNode>::iterator act_itr = adjSet.find(actor); 
     if(act_itr != adjSet.end()){ 
      //in the set 
      auto mov_itr = act_itr->movies.find(movie); 
      if(mov_itr == act_itr->movies.end()){ 
       act_itr->movies.insert(movie) //no matching function, while act_itr->movies is of type unordered_set<Movie> 
      } 
     } 
    }else{ 
     unordered_set<ActorNode> adjSet; 
     actor.movies.insert(movie); 
     adjSet.insert(actor); 
     connections[actor_name] = adjSet; 
     cout << "The size is: " << actor.movies.size() << endl; 
    } 
} 

Mon ActorNode est une struct qui ressemble à ce

struct ActorNode{ 
    //the name of the actor/actress 
    string name; 

    /** the movie that this actor/actree participated in 
    */ 
    unordered_set<Movie> movies; 

    ActorNode(string n) : name(n){} 

    bool operator ==(const ActorNode &other) const; 
}; 


namespace std 
{ 
    template <> 
    struct hash<ActorNode> 
    { 
     size_t operator()(const ActorNode& actor) const 
     { 
      return hash<std::string>{}(actor.name); 
     } 
    }; 
} 

struct Film

#ifndef Movie_h 
#define Movie_h 

#include <iostream> 
using namespace std; 

struct Movie{ 
    string name; 
    int year; 
    Movie(string n, int y): name(n), year(y){} 
    bool operator ==(const Movie &m) const; 
}; 



namespace std 
{ 
    template <> 
    struct hash<Movie> 
    { 
     size_t operator()(const Movie& movie) const 
     { 
      return hash<std::string>{}(movie.name + to_string(movie.year)); 
     } 
    }; 
} 


#endif /* Movie_ph*/ 

enter image description here

J'ai mis en œuvre et l'emportaient sur l'opérateur et faire à la fois mon Movie et ActorNode struct compatible pour l'utilisation dans le clé de unordered_set

Voici le dépôt: Repo


Minimal Reproduction Example

#include <iostream> 
#include <string> 
#include <unordered_set> 

struct Movie{ 
    std::string name; 
    int year; 

    Movie(std::string n, int y): name(std::move(n)), year(y) 
    { 
    } 

    bool operator ==(const Movie &m) const 
    { 
     return year == m.year && name == m.name; 
    }; 
}; 


namespace std 
{ 
    template <> 
    struct hash<Movie> 
    { 
     size_t operator()(const Movie& movie) const 
     { 
      return hash<std::string>{}(movie.name + to_string(movie.year)); 
     } 
    }; 
} 
//////////////////// 

struct ActorNode 
{ 
    std::string name; 
    std::unordered_set<Movie> movies; 

    ActorNode(std::string n) : name(std::move(n)) 
    { 
    } 

    bool operator ==(const ActorNode &other) const 
    { 
     return name == other.name; 
    } 
}; 


namespace std 
{ 
    template <> 
    struct hash<ActorNode> 
    { 
     size_t operator()(const ActorNode& actor) const 
     { 
      return hash<std::string>{}(actor.name); 
     } 
    }; 
} 
//////////////////// 


int main() 
{ 
    std::unordered_set<ActorNode> actors; 
    actors.emplace("Gene Wilder"); 

    auto itr = actors.find(ActorNode("Gene Wilder")); 
    if (itr != actors.end()) 
    { 
     // error: no matching function for call to     
     // 'std::unordered_set<Movie>::insert(Movie) const' 
     itr->movies.insert(Movie("Stir Crazy", 1980)); 
    } 
} 
+0

S'il vous plaît donner un exemple complet minimal. Et s'il vous plaît donner le message d'erreur entier. – JHBonarius

+0

Btw: Il vous manque un ';' à la fin de la ligne avec l'erreur ... – JHBonarius

+0

Ajoutée @WhozCraig –

Répondre

2

Le problème est que vous ne pouvez pas modifier la clé de set, car il peut conduire à set reconstruire, mais set sera ne pas être reconstruit, parce que vous venez de modifier la variable, rien d'autre. Donc, c'est explicitement interdit.

Définition de iterator dans unordered_set

iterator Constant ForwardIterator 
const_iterator Constant forward iterator 
+1

Je ne sais pas pourquoi je ne m'en souviens pas. Si je me souviens bien, les itérateurs (à la fois ordonnés et non) ont été faits 'const' pour éviter ce problème (les gens qui modifient set containment) en C++ 11 (il est tard et je suis fatigué, mais je * pense * que était quand il s'est emparé). – WhozCraig

+0

Bon à savoir à ce sujet, merci, je peux essayer de trouver un peu de travail autour –

+0

@KesongXie utiliser une carte (ordonnée ou non) à la place, la cartographie de la seule chose dont vous vous souciez probablement (les noms) aux objets connexes. La valeur mappée est librement modifiable dans ce cas. Vaut la peine d'être considéré. – WhozCraig