Dlaczego kompilator nie widzi przeładowanego operatora >> dla klasy z template?

0
    #include <iostream>
    #include <cstdint>
    using namespace std;
     
    template<class T>
    class integer_IO
    {
      T &val;
     
    public:
     
      integer_IO(T &arg) : val(arg) {}
     
      friend istream &operator>> (istream &is, integer_IO<T> &i)
      {
        decltype(+(i.val)) hlp;
        is >> hlp;
        i.val = hlp;
        return is;
      }
     
      friend ostream &operator<< (ostream &os, integer_IO<T> const &i)
      {
        os << +(i.val);
        return os;
      }
    };
     
    template<class T>
    integer_IO<T> intIO(T &arg)
    {
      return integer_IO<T>(arg);
    }
     
    int main()
    {
      int_least8_t i;
      cin >> intIO(i);
      cout << intIO(i) << '\n';
    }

Kod się nie kompiluje: http://ideone.com/15o5XZ
Nie jestem pewien, dlaczego. Czemu kompilator nie widzi odnośnego przeładowanego operatora i wyrzuca błędy?

1

Bo chcesz wczytać do zmiennej tymczasowej i nie istnieje przeciążona wersja >>, która potrafi to obsługiwać. Istniejąca wersja jako drugi argument ma referencję, więc nie pasuje.
Poza tym nawet gdyby jakimś cudem udało Ci się wczytać, to przecież przy wypisywaniu już masz zupełnie inną zmienną.

0

Uff. Naprawione:

15c15
<   friend istream &operator>> (istream &is, integer_IO<T> &i)
---
>   friend istream &operator>> (istream &is, integer_IO<T> &&i)
23c23
<   friend ostream &operator<< (ostream &os, integer_IO<T> const &i)
---
>   friend ostream &operator<< (ostream &os, integer_IO<T> const &&i)

Działa http://ideone.com/NTx6UI .

twonek napisał(a):

Poza tym nawet gdyby jakimś cudem udało Ci się wczytać, to przecież przy wypisywaniu już masz zupełnie inną zmienną.

Nie zupełnie inną. val jest przecież typu referencyjnego: T &val. Chyba, że czegoś znowu nie rozumiem.

0

No chyba nie rozumiesz bo działa to zupełnie przypadkiem i generalnie jest mega nieczytelne.
intIO to funkcja która zwraca kopię pewnego obiektu który w niej tworzysz. A ty do tej kopii próbujesz coś wpisać. Ta kopia oczywiśćie ginie zaraz po skończeniu wywołania i to ci "działa" tylko dlatego że ten obiekt pracował na oryginalnej zmiennej i którą przekazałeś przez referencje.
Normalny człowiek napisałby:

integer_IO<int> object = intIO(i);
cin>>object;
cout<<object;
0
Shalom napisał(a):

i to ci "działa" tylko dlatego że ten obiekt pracował na oryginalnej zmiennej i którą przekazałeś przez referencje.

Dokładnie to chciałem uzyskać

Shalom napisał(a):

Normalny człowiek napisałby:

integer_IO<int> object = intIO(i);
cin>>object;
cout<<object;

I właśnie tego chciałem uniknąć, bo mijałoby się to z celem, dla którego napisałem ten kawałek kodu. Zaraz go skończę, wstawię całość, napiszę co dokłądnie chciałem uzyskać i dlaczego, i wtedy będziecie mogli się natrząsać, że wszystko zrobiłem źle, OK?

1 użytkowników online, w tym zalogowanych: 0, gości: 1