1

I want to use iostream_iterator for tuple. I have overload input operator >> for the tuple. But compiler give compilation error.

#include <vector>
#include <iostream>
#include <algorithm>
#include <iterator>
#include <tuple>

using namespace std;
using rec_t= tuple<int, string>;

istream& operator>>(istream& strm, rec_t& r) {
strm>>get<0>(r)>>get<1>(r);
return strm;
}
int main() {
    int n;
    cin>>n;
    vector<rec_t> ar(n);
    copy_n(istream_iterator<rec_t>(cin), n, begin(ar));
    return 0;
}

The compiler error message is:

-------------- Build: Debug (compiler: GNU GCC Compiler)---------------

g++ -Wall -fexceptions -std=c++11 -g  -c main.cpp -o obj/Debug/main.o
In file included from /usr/include/c++/4.9/iterator:66:0,
                 from main.cpp:4:
/usr/include/c++/4.9/bits/stream_iterator.h: In instantiation of ‘void std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::_M_read() [with _Tp = std::tuple<int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >; _CharT = char; _Traits = std::char_traits<char>; _Dist = long int]’:
/usr/include/c++/4.9/bits/stream_iterator.h:70:17:   required from ‘std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_iterator(std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_type&) [with _Tp = std::tuple<int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >; _CharT = char; _Traits = std::char_traits<char>; _Dist = long int; std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_type = std::basic_istream<char>]’
main.cpp:18:39:   required from here
/usr/include/c++/4.9/bits/stream_iterator.h:121:17: error: cannot bind ‘std::istream_iterator<std::tuple<int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > > >::istream_type {aka std::basic_istream<char>}’ lvalue to ‘std::basic_istream<char>&&’
      *_M_stream >> _M_value;
                 ^
In file included from /usr/include/c++/4.9/iostream:40:0,
                 from main.cpp:2:
/usr/include/c++/4.9/istream:872:5: note: initializing argument 1 of ‘std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&&, _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = std::tuple<int, std::basic_string<char, std::char_traits<char>, std::allocator<char> > >]’
     operator>>(basic_istream<_CharT, _Traits>&& __is, _Tp& __x)
     ^
Process terminated with status 1 (0 minute(s), 1 second(s))
1 error(s), 3 warning(s) (0 minute(s), 1 second(s))

1 Answers1

1

You've fallen victim to ADL "argument dependent lookup".

You should go look it up, because there are good explanations out there. Basically, your operator >> should be in the same namespace as your rec_t.

But it's not - rec_t is in namespace std (since it's really std::tuple<int, std::string>), and operator >> is in the global namespace.

Marshall Clow
  • 15,972
  • 2
  • 29
  • 45