Questa è una specie di seguito alla domanda this.La risoluzione di sovraccarico si risolve in una funzione non ancora visibile
#include <iostream>
struct type1 {};
struct type2 {};
void foo(type1 x)
{
std::cout << "foo(type1)" << std::endl;
}
template<typename T>
void bar() {
foo(T());
}
int main()
{
bar<type1>();
bar<type2>();
return 0;
}
void foo(type2 x)
{
std::cout << "foo(type2)" << std::endl;
}
Nel codice precedente foo(type2)
non è visibile al momento di istanziazione di bar<type2>
in main
. Eppure il codice viene compilato e produce il seguente output:
foo(type1)
foo(type2)
Come fa il compilatore sa che foo(type2)
è disponibile quando si crea un'istanza bar<type2>
in main
?
EDIT: Sto cercando di capire di più su come funziona la risoluzione di sovraccarico durante l'istanziazione del modello. Si consideri il seguente codice:
#include <iostream>
struct type1 {};
struct type2 {};
struct type3 {
operator type2() { return type2(); }
};
void foo(type1 x)
{
std::cout << "foo(type1)" << std::endl;
}
void foo(type2 x)
{
std::cout << "foo(type2)" << std::endl;
}
int main()
{
foo(type3());
return 0;
}
void foo(type3 x)
{
std::cout << "foo(type3)" << std::endl;
}
L'uscita è
foo(type2)
Anche se una maggiore corrispondenza foo(type3)
è disponibile, la chiamata foo(type3())
risolve a foo(type2)
perché quello era l'unico candidato che è stato analizzato dal compilatore fino a quel punto. Consideriamo ora il seguente codice:
#include <iostream>
struct type1 {};
struct type2 {};
struct type3 {
operator type2() { return type2(); }
};
void foo(type2 x)
{
std::cout << "foo(type2)" << std::endl;
}
template<typename T>
void bar() {
foo(T());
}
int main()
{
bar<type3>();
return 0;
}
void foo(type3 x)
{
std::cout << "foo(type3)" << std::endl;
}
L'uscita è
foo(type3)
Cioè, nel punto della chiamata bar<type3>()
, anche se solo foo(type2)
è visibile, il compilatore prende ancora foo(type3)
che viene dopo, perché questa è una corrispondenza più stretta.
Il tuo codice si compila bene con GCC 4.6. – keveman
@keveman: citazione da [qui] (http://gcc.gnu.org/gcc-4.7/changes.html): 'G ++ ora implementa correttamente le regole di ricerca a due fasi in modo che un nome non qualificato utilizzato in un modello debba avere una dichiarazione appropriata trovata o nell'ambito nell'ambito del punto di definizione del modello o per la ricerca dipendente dall'argomento nel punto di istanziazione. implementato da gcc 4.7. –
Ok. Non funziona con gcc 4.7. Grazie. Tuttavia, ciò che mi ostacola è il fatto che, nel mio esempio, 'foo (tipo3)' non è disponibile né in ambito al punto di definizione del modello né in quello di istanziazione. Ancora questo è quello che viene chiamato. – keveman