gcc-3.1 istream_iterator bug

Gabriel Dos Reis gdr@integrable-solutions.net
Mon Aug 26 13:43:00 GMT 2002


nbecker@hns.com (Neal D. Becker) writes:

| This simple program fails to compile with gcc-3.1:
| 
| -------------------------------
| #include <iostream>
| #include <iterator>
| #include <vector>
| #include <utility>
| 
| template<typename charT, typename traits, typename T1, typename T2>
| inline std::basic_istream<charT,traits>& operator>> (std::basic_istream<charT,traits>& is, std::pair<T1,T2>& p) {
|   T1 t1;
|   T2 t2;
|   is >> t1 >> t2;
|   if (is)
|     p = std::pair<T1,T2> (t1, t2);
|   return is;
| }
| 
| int main () {
|   std::vector<int> v;
| 
|   typedef std::pair<double,double> pt;
| 
|   std::copy (std::istream_iterator<pt> (std::cin), std::istream_iterator<pt> (), std::back_inserter (v));
| }

Hi,

  The above program is expected to fail because of name lookup issues.

When copying a sequence to or from a stream, the inserter/extractor
operators are used.  And naturally, the relevant name lookup rule here
is "Koenig lookup".  For the specialization std::pair<double, double>,
the associated namespaces and classes is reduced to std::.  However
that namespace does -not- contain the extractor operator you defined
(which is the global namespace).  As a matter of fact, name lookup
finds no declaration for the suitable operator>>, hence the diagnostic
(cryptic, I admit).

A work around is

  1) invoke undefined behaviour and define your extractor in std::; or

  2) use user-defined types and define your extrator in the associated
     namespace (see Herb's Interface Principle).


-- Gaby



More information about the Gcc-bugs mailing list