Abhängige Namensauflösung und Namespace std / Standard Library

Während der Beantwortungdiese SO Frage (besser lesendieses "Duplikat") Habe ich mir folgende Lösung für die abhängige Namensauflösung eines Operators ausgedacht:

[temp.dep.res] / 1:

Bei der Auflösung abhängiger Namen werden Namen aus den folgenden Quellen berücksichtigt:

Deklarationen, die am Definitionspunkt der Vorlage sichtbar sind.Deklarationen von Namespaces, die den Typen der Funktionsargumente zugeordnet sind, stammen sowohl aus dem Instanziierungskontext (14.6.4.1) als auch aus dem Definitionskontext.
#include <iostream>
#include <utility>

// this operator should be called from inside `istream_iterator`
std::istream& operator>>(std::istream& s, std::pair<int,int>& p)
{
    s >> p.first >> p.second;
    return s;
}

// include definition of `istream_iterator` only after declaring the operator
// -> temp.dep.res/1 bullet 1 applies??
#include <iterator>

#include <map>
#include <fstream>

int main()
{
    std::ifstream in("file.in");

    std::map<int, int> pp; 
    pp.insert( std::istream_iterator<std::pair<int, int>>{in},
               std::istream_iterator<std::pair<int, int>>{} );
}

Aber clang ++ 3.2 und g ++ 4.8 finden diesen Operator nicht (Namensauflösung).

Ist das nicht die Einbeziehung von<iterator> Definieren Sie den "Definitionspunkt der Vorlage"istream_iterator?

Bearbeiten: AlsAndy Prowl weist darauf hin, dass dies nichts mit der Standardbibliothek zu tun hat, sondern vielmehr mit der Namenssuche (kann durch Nachahmen der Standardbibliothek mit mehreren nachgezeichnet werden)operator>>Mindestens eine im Namensraum der Fälschungistream).

Edit2: Eine Problemumgehung mit [basic.lookup.argdep] / 2 bullet 2

#include <iostream>
#include <utility>

// can include <iterator> already here,
// as the definition of a class template member function
// is only instantiated when the function is called (or explicit instantiation)
// (make sure there are no relevant instantiations before the definition
//  of the operator>> below)
#include <iterator>

struct my_int
{
    int m;
    my_int() : m() {}
    my_int(int p) : m(p) {}
    operator int() const { return m; }
};

// this operator should be called from inside `istream_iterator`
std::istream& operator>>(std::istream& s, std::pair<my_int,my_int>& p)
{
    s >> p.first.m >> p.second.m;
    return s;
}

#include <map>
#include <fstream>

int main()
{
    std::ifstream in("file.in");

    std::map<int, int> pp; 
    pp.insert( std::istream_iterator<std::pair<my_int, my_int>>{in},
               std::istream_iterator<std::pair<my_int, my_int>>{} );
}

Natürlich können Sie auch Ihre eigenen verwendenpair Typ, solange die Problemumgehung eine zugeordnete Klasse im Namespace der benutzerdefinierten einführtoperator>>.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage