Quand l'utilisation de std:: ref est-elle nécessaire?

prendre en considération:

std::tuple<int , const A&> func (const A& a) 
{
  return std::make_tuple( 0 , std::ref(a) );
}

Est le std::ref nécessaires à l'écriture correcte et code portable? (Il compile très bien sans elle)

Contexte:

si je supprime std::ref mon code se construit bien sans aucun avertissement ( g++-4.6 -Wall ), mais ne fonctionne pas correctement.

en cas d'intérêt la définition de A :

struct A {
  std::array<int,2> vec;
  typedef int type_t;

  template<typename... OPs,typename... VALs>
  A& operator=(const std::pair< std::tuple<VALs...> , std::tuple<OPs...> >& e) {
    for( int i = 0 ; i < vec.size() ; ++i ) {
      vec[i] = eval( extract(i,e.first) , e.second );
    }
  }
};
19
demandé sur ritter 2012-08-06 21:30:29

3 réponses

  • make_tuple(0, a) fait un tuple<int, A> .
  • make_tuple(0, ref(a)) fait un tuple<int, reference_wrapper<A>> .
  • vous pouvez aussi dire tuple<int, A&> t(0, a); pour un tuple que vous ne pouvez pas faire avec make_tuple , ou utiliser std::tie .
11
répondu Kerrek SB 2012-08-06 17:32:34

std::ref ne fait pas de référence, donc dans votre exemple de code il ne fait pas ce que vous attendez. std::ref crée un objet qui se comporte comme une référence. Il peut être utile, par exemple, lorsque vous voulez instancier un functor, et passer une version de référence de celui-ci à un algorithme de bibliothèque standard. Puisque les algorithmes prennent les foncteurs en valeur, vous pouvez utiliser std::ref pour envelopper le foncteur.

7
répondu juanchopanza 2012-08-06 17:35:21

L'un des exemples où std::ref est nécessaire:

void update(int &data)  //expects a reference to int
{
    data = 15;
}
int main()
{
    int data = 10;

    // This doesn't compile as the data value is copied when its reference is expected.
    //std::thread t1(update, data);         

    std::thread t1(update, std::ref(data));  // works

    t1.join();
    return 0;
}

le constructeur std::thread copie les valeurs fournies telles quelles, sans passer au type d'argument attendu (qui est référence type dans ce cas, voir update() ). Nous devons donc envelopper les arguments qui ont vraiment besoin d'être des références dans std::ref .

2
répondu Saurav Sahu 2017-08-22 17:24:45