Sono stato morso da questo problema un paio di volte e così ho i miei colleghi. Durante la compilazioneChiamata ambigua alla funzione di modello a causa di ADL
#include <deque>
#include <boost/algorithm/string/find.hpp>
#include <boost/operators.hpp>
template< class Rng, class T >
typename boost::range_iterator<Rng>::type find(Rng& rng, T const& t) {
return std::find(boost::begin(rng), boost::end(rng), t);
}
struct STest {
bool operator==(STest const& test) const { return true; }
};
struct STest2 : boost::equality_comparable<STest2> {
bool operator==(STest2 const& test) const { return true; }
};
void main() {
std::deque<STest> deq;
find(deq, STest()); // works
find(deq, STest2()); // C2668: 'find' : ambiguous call to overloaded function
}
... il compilatore VS9 non riesce durante la compilazione della seconda ricerca. Ciò è dovuto al fatto che STest2
eredita da un tipo definito nello spazio dei nomi boost che attiva il compilatore per provare ADL che trova boost::algorithm::find(RangeT& Input, const FinderT& Finder)
.
Una soluzione ovvia è quella di anteporre la chiamata a find(…)
con "::
", ma perché questo è necessario? C'è una corrispondenza perfettamente valida nello spazio dei nomi globale, quindi perché invocare la ricerca dipendente dall'argomento? Qualcuno può spiegare la logica qui?
Si noti che la partita non è perfetta. Una funzione non-template 'find (std :: deque, STest)' sarebbe una corrispondenza migliore. –
MSalters
@MSalters: hai ragione, naturalmente. La corrispondenza nello spazio dei nomi globale non è perfetta. Penso che mi aspettavo che ADL fosse un'eccezione, utilizzata per trovare una corrispondenza strettamente migliore in uno spazio dei nomi più remoto. Le risposte mostrano che questo è un fraintendimento. – Sebastian
La mia domanda è perché ADL sta trovando una funzione all'interno di 'boost :: algorithm' quando l'argomento è una classe nello spazio dei nomi globale, che eredita da una classe nello spazio dei nomi' boost :: detail' ... e la risposta è una 'usando l'algoritmo :: find' nell'intestazione' 'che porta la funzione nello spazio dei nomi' boost'. Potrebbe essere un difetto? Questo non dovrebbe essere per lo meno opzionale? –