rispondendo this SO question (meglio leggere this "duplicate"), mi si avvicinò con la seguente soluzione per la risoluzione dei nomi a carico di un operatore:Dependent risoluzione dei nomi e namespace std/Standard Biblioteca
[temp.dep.res]/1:
Nella risoluzione nomi dipendenti, i nomi dalle seguenti fonti sono considerati:
- dichiarazioni che sono visibili al momento della definizione del modello.
- Dichiarazioni dai namespace associati ai tipi degli argomenti della funzione sia dal contesto di istanziazione (14.6.4.1) che dal contesto di definizione.
#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>>{});
}
Ma clang ++ 3.2 e 4.8 g ++ non trovano questo operatore (risoluzione dei nomi).
L'inclusione di non definisce il "punto di definizione del modello"
istream_iterator
?
Edit: Come Andy Prowl sottolinea, questo non ha nulla a che fare con la libreria standard, ma piuttosto con la ricerca del nome (può essere provata imitando la libreria standard con più operator>>
, almeno uno nello spazio dei nomi del falso istream
).
Edit2: Una soluzione, utilizzando [basic.lookup.argdep]/2 proiettile 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>>{});
}
Naturalmente, è anche possibile utilizzare il proprio pair
tipo, a condizione che la soluzione introduce un classe associata nello spazio dei nomi dell'abitudine operator>>
.
Potete fornire un riferimento per favore? :) Sono ansioso di dare un'occhiata allo Standard – dyp
@DyP: La mia risposta ha bisogno di essere modificata;) Ci lavorerò sopra –
Ok, ho capito :) [basic.lookup.unqual]/1; la ricerca in spazi dei nomi associati/ricerca dipendente dall'argomento non funziona qui poiché entrambi i tipi provengono da 'namespace std'. – dyp