Overload >> ifstream_iterator for pairs

I am trying to build ifstream_iterator in a couple. My code is as follows:

typedef pair<float, int> T; istream& operator>>(istream& stream, T& in) { stream >> in.first >> in.second; return stream; } int main(int argc, char **argv) { ifstream infile("dummy2"); istream_iterator<T> iit(infile); istream_iterator<T> eos; while (iit != eos) { cout << (*iit).first << endl; ++iit; } return 0; } 

I have a dummy file "dummy2" as follows:

 "a" 4 "b" 5 

I would like to output the pairs {"a", 4} and {"b", 5}.

However, I get an unpleasant compilation error

 In file included from /usr/include/c++/4.6/iterator:66:0, from filestream.cpp:9: /usr/include/c++/4.6/bits/stream_iterator.h: In member function 'void std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::_M_read() [with _Tp = std::pair<float, int>, _CharT = char, _Traits = std::char_traits<char>, _Dist = long int]': /usr/include/c++/4.6/bits/stream_iterator.h:70:9: instantiated from 'std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_iterator(std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_type&) [with _Tp = std::pair<float, int>, _CharT = char, _Traits = std::char_traits<char>, _Dist = long int, std::istream_iterator<_Tp, _CharT, _Traits, _Dist>::istream_type = std::basic_istream<char>]' filestream.cpp:32:33: instantiated from here /usr/include/c++/4.6/bits/stream_iterator.h:121:6: error: no match for 'operator>>' in '*((std::istream_iterator<std::pair<float, int> >*)this)->std::istream_iterator<std::pair<float, int> >::_M_stream >> ((std::istream_iterator<std::pair<float, int> >*)this)->std::istream_iterator<std::pair<float, int> >::_M_value' /usr/include/c++/4.6/bits/stream_iterator.h:121:6: note: candidates are: /usr/include/c++/4.6/istream:122:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>::__istream_type& (*)(std::basic_istream<_CharT, _Traits>::__istream_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] /usr/include/c++/4.6/istream:122:7: note: no known conversion for argument 1 from 'std::pair<float, int>' to 'std::basic_istream<char>::__istream_type& (*)(std::basic_istream<char>::__istream_type&) {aka std::basic_istream<char>& (*)(std::basic_istream<char>&)}' /usr/include/c++/4.6/istream:126:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>::__ios_type& (*)(std::basic_istream<_CharT, _Traits>::__ios_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>, std::basic_istream<_CharT, _Traits>::__ios_type = std::basic_ios<char>] /usr/include/c++/4.6/istream:126:7: note: no known conversion for argument 1 from 'std::pair<float, int>' to 'std::basic_istream<char>::__ios_type& (*)(std::basic_istream<char>::__ios_type&) {aka std::basic_ios<char>& (*)(std::basic_ios<char>&)}' /usr/include/c++/4.6/istream:133:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(std::ios_base& (*)(std::ios_base&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] /usr/include/c++/4.6/istream:133:7: note: no known conversion for argument 1 from 'std::pair<float, int>' to 'std::ios_base& (*)(std::ios_base&)' /usr/include/c++/4.6/istream:169:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(bool&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] /usr/include/c++/4.6/istream:169:7: note: no known conversion for argument 1 from 'std::pair<float, int>' to 'bool&' /usr/include/c++/4.6/istream:173:7: note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(short int&) [with _CharT = char, _Traits = std::char_traits<char>] /usr/include/c++/4.6/istream:173:7: note: no known conversion for argument 1 from 'std::pair<float, int>' to 'short int&' /usr/include/c++/4.6/istream:176:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(short unsigned int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] /usr/include/c++/4.6/istream:176:7: note: no known conversion for argument 1 from 'std::pair<float, int>' to 'short unsigned int&' /usr/include/c++/4.6/istream:180:7: note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(int&) [with _CharT = char, _Traits = std::char_traits<char>] /usr/include/c++/4.6/istream:180:7: note: no known conversion for argument 1 from 'std::pair<float, int>' to 'int&' /usr/include/c++/4.6/istream:183:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(unsigned int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] /usr/include/c++/4.6/istream:183:7: note: no known conversion for argument 1 from 'std::pair<float, int>' to 'unsigned int&' /usr/include/c++/4.6/istream:187:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] /usr/include/c++/4.6/istream:187:7: note: no known conversion for argument 1 from 'std::pair<float, int>' to 'long int&' /usr/include/c++/4.6/istream:191:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long unsigned int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] /usr/include/c++/4.6/istream:191:7: note: no known conversion for argument 1 from 'std::pair<float, int>' to 'long unsigned int&' /usr/include/c++/4.6/istream:196:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long long int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] /usr/include/c++/4.6/istream:196:7: note: no known conversion for argument 1 from 'std::pair<float, int>' to 'long long int&' /usr/include/c++/4.6/istream:200:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long long unsigned int&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] /usr/include/c++/4.6/istream:200:7: note: no known conversion for argument 1 from 'std::pair<float, int>' to 'long long unsigned int&' /usr/include/c++/4.6/istream:205:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(float&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] /usr/include/c++/4.6/istream:205:7: note: no known conversion for argument 1 from 'std::pair<float, int>' to 'float&' /usr/include/c++/4.6/istream:209:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(double&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] /usr/include/c++/4.6/istream:209:7: note: no known conversion for argument 1 from 'std::pair<float, int>' to 'double&' /usr/include/c++/4.6/istream:213:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(long double&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] /usr/include/c++/4.6/istream:213:7: note: no known conversion for argument 1 from 'std::pair<float, int>' to 'long double&' /usr/include/c++/4.6/istream:217:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(void*&) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] /usr/include/c++/4.6/istream:217:7: note: no known conversion for argument 1 from 'std::pair<float, int>' to 'void*&' /usr/include/c++/4.6/istream:241:7: note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>::__streambuf_type*) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__streambuf_type = std::basic_streambuf<char>] /usr/include/c++/4.6/istream:241:7: note: no known conversion for argument 1 from 'std::pair<float, int>' to 'std::basic_istream<char>::__streambuf_type* {aka std::basic_streambuf<char>*}' /usr/include/c++/4.6/bits/basic_string.tcc:998:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::basic_string<_CharT, _Traits, _Alloc>&) /usr/include/c++/4.6/bits/random.tcc:923:5: note: template<class _IntType, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::uniform_int_distribution<_IntType>&) /usr/include/c++/4.6/bits/random.tcc:968:5: note: template<class _RealType, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::uniform_real_distribution<_RealType>&) /usr/include/c++/4.6/bits/random.tcc:1890:5: note: template<class _RealType, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::cauchy_distribution<_RealType>&) /usr/include/c++/4.6/bits/random.h:3381:5: note: template<class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::bernoulli_distribution&) /usr/include/c++/4.6/bits/random.tcc:1733:5: note: template<class _RealType1, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::normal_distribution<_RealType1>&) /usr/include/c++/4.6/bits/random.tcc:1063:5: note: template<class _IntType, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::geometric_distribution<_IntType>&) /usr/include/c++/4.6/bits/random.tcc:2085:5: note: template<class _RealType1, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::gamma_distribution<_RealType1>&) /usr/include/c++/4.6/bits/random.tcc:1622:5: note: template<class _RealType, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::exponential_distribution<_RealType>&) /usr/include/c++/4.6/bits/random.tcc:2143:5: note: template<class _RealType, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::weibull_distribution<_RealType>&) /usr/include/c++/4.6/bits/random.tcc:2200:5: note: template<class _RealType, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::extreme_value_distribution<_RealType>&) /usr/include/c++/4.6/bits/random.tcc:194:5: note: template<class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::linear_congruential_engine<_UIntType, __a, __c, __m>&) /usr/include/c++/4.6/bits/random.tcc:491:5: note: template<class _UIntType, long unsigned int __w, long unsigned int __n, long unsigned int __m, long unsigned int __r, _UIntType __a, long unsigned int __u, _UIntType __d, long unsigned int __s, _UIntType __b, long unsigned int __t, _UIntType __c, long unsigned int __l, _UIntType __f, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>&) /usr/include/c++/4.6/bits/random.tcc:642:5: note: template<class _UIntType, long unsigned int __w, long unsigned int __s, long unsigned int __r, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::subtract_with_carry_engine<_UIntType, __w, __s, __r>&) /usr/include/c++/4.6/bits/random.tcc:709:5: note: template<class _RandomNumberEngine, long unsigned int __p, long unsigned int __r, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::discard_block_engine<_RandomNumberEngine, __p, __r>&) /usr/include/c++/4.6/bits/random.tcc:815:5: note: template<class _RandomNumberEngine, long unsigned int __k, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::shuffle_order_engine<_RandomNumberEngine, __k>&) /usr/include/c++/4.6/bits/random.tcc:1138:5: note: template<class _IntType, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::negative_binomial_distribution<_IntType>&) /usr/include/c++/4.6/bits/random.tcc:1328:5: note: template<class _IntType, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::poisson_distribution<_IntType>&) /usr/include/c++/4.6/bits/random.tcc:1577:5: note: template<class _IntType, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::binomial_distribution<_IntType>&) /usr/include/c++/4.6/bits/random.tcc:1782:5: note: template<class _RealType, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::lognormal_distribution<_RealType>&) /usr/include/c++/4.6/bits/random.tcc:1827:5: note: template<class _RealType, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::chi_squared_distribution<_RealType>&) /usr/include/c++/4.6/bits/random.tcc:1936:5: note: template<class _RealType, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::fisher_f_distribution<_RealType>&) /usr/include/c++/4.6/bits/random.tcc:1981:5: note: template<class _RealType, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::student_t_distribution<_RealType>&) /usr/include/c++/4.6/bits/random.tcc:2308:5: note: template<class _IntType, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::discrete_distribution<_IntType>&) /usr/include/c++/4.6/bits/random.tcc:2488:5: note: template<class _RealType, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::piecewise_constant_distribution<_RealType>&) /usr/include/c++/4.6/bits/random.tcc:2690:5: note: template<class _RealType, class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::piecewise_linear_distribution<_RealType>&) /usr/include/c++/4.6/bits/istream.tcc:957:5: note: template<class _CharT2, class _Traits2> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, _CharT2*) /usr/include/c++/4.6/bits/istream.tcc:925:5: note: template<class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, _CharT&) /usr/include/c++/4.6/istream:709:5: note: template<class _Traits> std::basic_istream<char, _Traits>& std::operator>>(std::basic_istream<char, _Traits>&, unsigned char&) /usr/include/c++/4.6/istream:714:5: note: template<class _Traits> std::basic_istream<char, _Traits>& std::operator>>(std::basic_istream<char, _Traits>&, signed char&) /usr/include/c++/4.6/istream:756:5: note: template<class _Traits> std::basic_istream<char, _Traits>& std::operator>>(std::basic_istream<char, _Traits>&, unsigned char*) /usr/include/c++/4.6/istream:761:5: note: template<class _Traits> std::basic_istream<char, _Traits>& std::operator>>(std::basic_istream<char, _Traits>&, signed char*) /usr/include/c++/4.6/istream:852:5: note: std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&&, _Tp&) [with _CharT = char, _Traits = std::char_traits<char>, _Tp = std::pair<float, int>] <near match> /usr/include/c++/4.6/istream:852:5: note: no known conversion for argument 1 from 'std::istream_iterator<std::pair<float, int> >::istream_type {aka std::basic_istream<char>}' to 'std::basic_istream<char>&&' /usr/include/c++/4.6/iomanip:70:5: note: template<class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::_Resetiosflags) /usr/include/c++/4.6/iomanip:100:5: note: template<class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::_Setiosflags) /usr/include/c++/4.6/iomanip:131:5: note: template<class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::_Setbase) /usr/include/c++/4.6/iomanip:169:5: note: template<class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::_Setfill<_CharT>) /usr/include/c++/4.6/iomanip:199:5: note: template<class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::_Setprecision) /usr/include/c++/4.6/iomanip:229:5: note: template<class _CharT, class _Traits> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::_Setw) /usr/include/c++/4.6/iomanip:263:5: note: template<class _CharT, class _Traits, class _MoneyT> std::basic_istream<_CharT, _Traits>& std::operator>>(std::basic_istream<_CharT, _Traits>&, std::_Get_money<_MoneyT>) make: *** [filestream] Error 1 

I can not understand what is happening here. Any help is appreciated. Many thanks!

+5
source share
2 answers

You will notice that just this:

 T t; infile >> t; 

It works like a charm! What's happening?

std::pair declared in the std .

istream_iterator<> really uses operator>> , and it does this using ADL during instance creation (this is called two-phase lookup).

However, during the instantiation, it will not consider your operator>> , since it does not exist in the namespace that implements istream_iterator , and none of them were declared in any of the associated namespaces implied by the arguments (this is ADL).

You may be tempted to β€œfix” it by specifying your overload in the std (and it works), but this is not permitted by the standard and technically leads to Undefined Behavior .

So, you better enter a type that allows ADL to use:

 struct T : public std::pair<int,float> {}; 

Live on coliru

 #include <utility> #include <iostream> #include <iterator> struct T : std::pair<float, int> { using std::pair<float, int>::pair; }; std::istream& operator>>(std::istream& stream, T& in) { return stream >> in.first >> in.second; } int main() { std::istream_iterator<T> iit(std::cin); std::istream_iterator<T> eos; while (iit != eos) { std::cout << (*iit).first << std::endl; ++iit; } } 

I suspect that theoretically you should be able to cheat things by reordering, turning on and introducing overloading early enough to be β€œvisible” during the first stage of the name search. However, whether this option depends on the implementation, and if you are out of luck, you still could not achieve it without changing the standard library headers ( do not do this ).

+5
source

This is a fairly common problem for which there is no really clean solution. It usually works to put your statement in namespace std :

 typedef pair<float, int> T; namespace std { istream& operator>>(istream& stream, T& in) { stream >> in.first >> in.second; return stream; } } int main(int argc, char **argv) { ifstream infile("dummy2"); istream_iterator<T> iit(infile); istream_iterator<T> eos; while (iit != eos) { cout << (*iit).first << endl; ++iit; } return 0; } 

Officially, this gives undefined behavior - you can add some specializations to namespace std , but you cannot add overloads there. Unofficially, I have not yet seen the compiler / library where this caused the problem.

+2
source

Source: https://habr.com/ru/post/1211552/


All Articles