2017-10-06 1 views
1

J'expérimente avec std::reference_wrapper. Je ne comprends pas pourquoi ce qui suit fonctionne avec un std::vector mais pas pour un std::unordered_map:affectation de valeur unordered_map lorsque le type de valeur est reference_wrapper

#include <functional> 
#include <vector> 
#include <unordered_map> 

using namespace std; 

int main() 
{ 
    vector<vector<long>> x; 

    vector<reference_wrapper<vector<vector<long>>>> y; 
    y.push_back(ref(x)); // OK 

    unordered_map<string, reference_wrapper<vector<vector<long>>>> m; 
    m["lol"] = ref(x); // NOT OK 
} 

Ceci est l'erreur de compilation que je reçois

/usr/include/c++/7.2.0/tuple:1652:70: error: no matching function for call to ‘std:: 
reference_wrapper<std::vector<std::vector<long int> > >::reference_wrapper()’  
     second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...) 
                    ^
In file included from /usr/include/c++/7.2.0/bits/std_function.h:44:0,    
       from /usr/include/c++/7.2.0/functional:58,       
       from test.cpp:1:   
/usr/include/c++/7.2.0/bits/refwrap.h:325:7: note: candidate: constexpr std::referen 
ce_wrapper<_Tp>::reference_wrapper(const std::reference_wrapper<_Tp>&) [with _Tp = s 
td::vector<std::vector<long int> >]  
     reference_wrapper(const reference_wrapper&) = default;      
     ^~~~~~~~~~~~~~~~~ 
/usr/include/c++/7.2.0/bits/refwrap.h:325:7: note: candidate expects 1 argument, 0 
provided    
/usr/include/c++/7.2.0/bits/refwrap.h:319:7: note: candidate: std::reference_wrapper 
<_Tp>::reference_wrapper(_Tp&) [with _Tp = std::vector<std::vector<long int> >]  
     reference_wrapper(_Tp& __indata) noexcept          
     ^~~~~~~~~~~~~~~~~ 
/usr/include/c++/7.2.0/bits/refwrap.h:319:7: note: candidate expects 1 argument, 0 
provided 

Quelqu'un peut-il expliquer ce que je fais mal?

Répondre

5

m["lol"] utilise les cartes non numérotées operator[]. Cet opérateur renvoie une référence à l'élément dans la carte. Ce qui est problématique s'il n'y a pas un tel élément.

Pour résoudre ce problème, il construira par défaut l'élément qu'il est censé renvoyer. Et voici le problème, car std::reference_wrapper n'est pas constructible par défaut.

Pour rendre les deux exemples plus équivalents, vous devez utiliser std::unordered_map::insert ou std::unordered_map::emplace.

+0

Ah! Logique! Juste essayé avec 'm.insert ({" lol ", ref (x)});' et cela a fonctionné. Merci :) – valentin