2016-10-09 2 views
1

Betrachten Sie das folgende ProgrammFehler C2672: ‚Operator __surrogate_func‘: keine passende überlastet gefunden Funktion, wenn std :: upper_bound

struct slot { 
    int item; 
    bool operator<(const int& right) const { 
     return item < right; 
    } 
    slot(int item) : item(item) {} 
}; 
int main() { 
    std::vector<slot> rails; 
    std::lower_bound(cbegin(rails), cend(rails), 5); 
    std::upper_bound(cbegin(rails), cend(rails), 5); 
} 

Ich bin mit std :: upper_bound um binäre Suche einen Vektor aber fehlschlägt, während

Kompilieren
c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm(2609): error C2672: 'operator __surrogate_func': no matching overloaded function found 

In Anbetracht der Tatsache, dass std::upperboundoperator< für implizite Vergleich verwendet, ohne ein Prädikat verwendet wird, kann ich nicht einen berechtigten Grund für den Compiler zu meckern finden. Außerdem ist die Fehlermeldung nicht ganz sinnvoll, da ich hier keinen Grund sehe, eine Ersatzfunktion zu verwenden. Auch wenn es sich um einen Funktor less<> handelt, sollte dies kein Problem sein, da slot weniger mit einer Ganzzahl vergleichbar ist. Es ist erwähnenswert, dass std::lower_bound eine akzeptable Syntax hat.

Siehe: http://rextester.com/WKK72283

+0

Wo ist der 'return' in Ihrem Betreiber Umsetzung? – AnT

+0

@AnT: Obwohl die Rückkehr sollte da sein, aber das sollte nicht der Grund sein, kompilieren, um zu scheitern – Abhijit

+0

Sie finden den Rest in meiner Antwort unten. – AnT

Antwort

2

Da die Spezifikationen der std::upper_bound eindeutig fest, es den Vergleich mit dem Argument-Wert auf der linken Seite und der Sequenzelement auf der rechten Seite gilt. I.e. in Ihrem Fall wäre das int < slot Vergleich. Ihr operator < unterstützt keine Vergleiche, die in dieser bestimmten Reihenfolge angeordnet sind.

Für std::upper_bound finden Sie

bool operator <(int left, const slot &s) 
{ 
    return left < s.item; 
} 

müssen, die als Member-Funktion nicht implementiert werden können.

Unterdessen wendet std::lower_bound die Vergleiche mit dem Argumentwert auf der rechten Seite an, d. H. slot < int Vergleiche.

Ihre ursprüngliche Implementierung funktioniert für std::lower_bound, aber nicht für std::upper_bound.

+0

Ja, das ist die Antwort, nach der ich gesucht habe. Darüber hinaus war dies zumindest für mich nicht ganz intuitiv, bis ich den Standard 25.4.3.2 'Returns: Der am weitesten entfernte Iterator i im Bereich [first, last] so bezeichnet habe, dass für jeden Iterator j im Bereich [first, i] der Folgende entsprechende Bedingungen gelten:! (Wert <* j) oder comp (Wert, * j) == false.' – Abhijit

0

Wie in der obigen Antwort vorgeschlagen, kann Ihr Problem gelöst werden, wenn die operator < implementiert werden kann, um 2 Argumente zu nehmen, aber dies wird der Implementierung der Elementfunktion widersprechen. Aber was ist, wenn dies eine friend Funktion wird. Es stellt sich heraus, dass das obige Problem gelöst werden kann, indem es als Freund-Funktion deklariert wird.

So wird Ihr Code etwas wie folgt aussehen:

struct slot { 
    int item; 

    friend bool operator<(int left, const slot &s) 
    { 
     return left < s.item; 
    } 

    friend bool operator<(const slot &s, int left) 
    { 
     return s.item < left; 
    } 

    slot(int item) : item(item) {} 
}; 
Verwandte Themen