68 votes

Ce comportement std::ref est-il logique ?

Considérez ce code :

#include <iostream>
#include <functional>

int xx = 7;

template<class T>
void f1(T arg)
{
    arg += xx;
}

template<class T>
void f2(T arg)
{
    arg = xx;
}

int main()
{
    int j;

    j=100;
    f1(std::ref(j));
    std::cout << j << std::endl;

    j=100;
    f2(std::ref(j));
    std::cout << j << std::endl;
}

Lorsqu'il est exécuté, ce code produit

107
100

Je me serais attendu à ce que la deuxième valeur soit 7 plutôt que 100.

Qu'est-ce que je rate ?

57voto

Richard Hodges Points 1972

Une petite modification à f2 fournit l'indice :

template<class T>
void f2(T arg)
{
    arg.get() = xx;
}

Cela fait maintenant ce que vous attendez.

Cela s'est produit parce que std::ref renvoie un std::reference_wrapper<> objet. L'opérateur d'affectation dont relier l'enveloppe. (voir http://en.cppreference.com/w/cpp/utility/functional/reference_wrapper/operator%3D )

Il n'effectue pas d'affectation à la référence enveloppée.

Dans le f1 Dans ce cas, tout fonctionne comme prévu car une std::reference_wrapper<T> fournit un opérateur de conversion pour T& qui se liera à la partie droite implicite de int s implicite operator+ .

12voto

Jarod42 Points 15729

reference_wrapper a operator = et un constructeur non explicite, voir documentation .

Donc, même si c'est surprenant, c'est le comportement normal :

f2 lie à nouveau le reference_wrapper local à xx .

10voto

Mohit Jain Points 6202

arg = xx;

Local arg se réfère maintenant à (lire comme se lie avec) xx . (Et ne se réfère plus à j )

arg += xx;

Implicite operator T& () est appliqué pour correspondre à l'argument de operator += et donc l'addition est effectuée sur l'objet référencé, c'est-à-dire j .

Le comportement observé est donc correct.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X