2017-08-10 7 views
1

Compiler-Fehler "Keine passende Funktion für Aufruf an" in meinem Fall eine Suchfunktion in einer verketteten Liste.Keine passende Funktion für Aufruf in verknüpfter Liste zu finden

Warum dieser Fehler?

Funktion

template<class T> 
int find(std::shared_ptr<Node<T>> ptr, T val) { 
    int pos(0); 
    while (ptr) { 
     if (ptr->val == val) 
      return pos; 
     else { 
      ptr = ptr->next; 
      pos++; 
     } 
    } 
    return -1; // Not found 
} 

Invocation

std::cout << "Pos: " << find(myFloat, 9.83) << std::endl; 

myFloat a shared_ptr ist und Wurzelknoten für eine Liste von Schwimmern, bevölkert erfolgreich wie folgt:

verketteten Liste von Floa ts

2.5 ⟹ 3.7 ⟹ 4.8 ⟹ 7.93 ⟹ 0.96 ⟹ 9.83 ⟹ 7.45 

Struct

template<class T> 
struct Node { 
    Node(T k):val(k){} 
    T val; 
    std::shared_ptr<Node<T>> next = nullptr; 
}; 

Fehler

keine passende Funktion für Aufruf von 'finden'

myFloat Definition

std::shared_ptr<Node<float>> myFloat = { std::make_shared<Node<float>>(0.) }; 
+0

Wie ist 'myFloat' definiert? – DimChtz

+0

Aktualisiert mit '' myFloat'' Definition – kmiklas

+0

[OT]: Da 'find' nicht Besitz übernimmt, besser durch Referenz/Zeiger anstelle von Smart Pointer – Jarod42

Antwort

3

Da Sie keine expliziten Template-Argumente zu find (wie in find<float>(myFloat, 9.83)) vorsah, muss der Compiler das Template-Argument T aus den Funktionsargumenten abzuleiten.

Während der Templatargumentableitung wird jedes Erscheinungsbild eines Template-Parameters in den Funktionsparametertypen entweder in einem abgeleiteten Kontext oder einem nicht-abgeleiteten Kontext angezeigt. In Ihrem Fall werden beide als abgeleiteter Kontext betrachtet. Ein Typ oder Wert wird für jede Darstellung eines Vorlagenparameters in einem abgeleiteten Kontext bestimmt.

myFloatstd::shared_ptr<Node<float>> hat und der erste Funktionsparameter eingeben hat std::shared_ptr<Node<T>> Typen, so wie Tfloat abgeleitet wird.

9.83 hat double-Typ und der zweite Funktionsparameter hat T eingeben, so T als Doppel abgeleitet wird.

Da der Vorlagenparameter T zu zwei verschiedenen Typen abgeleitet wurde, schlägt der Gesamtabzug fehl! Wenn der gleiche Template-Parameter mehr als einmal abgeleitet wird, müssen alle Ergebnisse identisch sein.

Was können Sie tun, damit dies funktioniert?

Eine unangenehme Lösung wäre, die Vorlage in Ruhe zu lassen und die Anrufer zu bitten, sie vorsichtig zu verwenden. find<float>(myFloat, 9.83) würde funktionieren, indem das Template-Argument explizit bereitgestellt wird. find(myFloat, 9.83f) würde funktionieren, indem Sie den Typ des zweiten Funktionsarguments ändern. Aber es ist besser, die Vorlage flexibler und freundlicher zu gestalten.

Eine einfache Lösung besteht darin, einfach zwei verschiedene Vorlagenparameter zu verwenden.

template<class T, class U> 
int find(std::shared_ptr<Node<T>> ptr, U val); 

Dann erfordert die Funktion einfach, dass der == Operator für die Typen arbeitet T und U.

Oder wenn Sie die zweite Funktion Argument wollen implizit auf den in den Node verwendeten Typ umgewandelt wird, könnten Sie absichtlich die zweite Verwendung von T in einen nicht abgeleiteten Kontext drehen:

template <typename T> 
struct identity { 
    using type = T; 
}; 

template<class T> 
int find(std::shared_ptr<Node<T>> ptr, 
     typename identity<T>::type val); 

von Erschienenen links von :: ist der zweite T jetzt ein nicht-abgeleiteter Kontext, daher wird der Ausdruck find(myFloat, 9.83) nur vom ersten Argument T ableiten, was zu T=float führt, dann in die Template-Funktionsdeklaration ersetzen. typename identity<float>::type funktioniert bis float, so wird es eine implizite Umwandlung von double Literal 9.83 zu float geben, um die Funktion aufzurufen.

Verwandte Themen