20

To bardziej wyrafinowane pytanie wspomniano w How does overload resolution work when an argument is an overloaded function?Jak działa dedukcja argumentu szablonu, gdy jako argument wykorzystywana jest funkcja przeciążenia?

poniższy kod compiles without any problem:

void foo() {} 
void foo(int) {} 
void foo(double) {} 
void foo(int, double) {} 

// Uncommenting below line break compilation 
//template<class T> void foo(T) {} 

template<class X, class Y> void bar(void (*f)(X, Y)) 
{ 
    f(X(), Y()); 
} 

int main() 
{ 
    bar(foo); 
} 

nie wydaje się trudnym zadaniem dla odliczenia szablon argumentów - istnieje tylko jedna funkcja, która przyjmuje dwa foo() argumenty. Jednak odkomentowanie przeciążenia szablonu foo() (które nadal ma tylko jeden parametr) powoduje przerwanie kompilacji bez oczywistego powodu. Kompilacja kończy się niepowodzeniem zarówno z gcc 5.x/6.x jak i klangiem 3.9.

Czy można to wytłumaczyć regułami rozwiązywania problemów z odciążeniem/szablonem, czy też należy je zakwalifikować jako wadę w tych kompilatorach?

+3

Jest to wyjaśnione w sekcji 13.3 C++ standard;) –

Odpowiedz

19

Jak wspomniano w odpowiedzi na połączonego pytanie:

[temp.deduct.call]/6: Kiedy P jest rodzajem funkcji, wskaźnik funkcjonować typ, albo wskaźnik do typu funkcji członka:

- Jeśli argument jest zestaw przeciążeniowy zawierający jeden lub więcej szablonów funkcji, parametr traktowany jest jako nie wywnioskowany kontekst.

Ponieważ zestaw przeciążeniowy zawiera szablon funkcji, parametr traktowany jest jako kontekst niewynikający. To powoduje, że szablon odliczenie argumentu na niepowodzenie:

[temp.deduct.type]/4: [...] Jeśli parametr szablon jest używany tylko w niewyspecjalizowanych wywnioskować kontekstach i nie jest wyraźnie określona, ​​odliczenie szablon argumentu nie powiedzie się.

I to nieudane odliczenie daje ci błąd. Zauważ, że jeśli jawnie określić argumenty, kod kompiluje pomyślnie:

bar<int,double>(foo); 

Live demo

Powiązane problemy