ist dieses C ++ - Beispiel portierbar?

8

diese Frage, ich versucht, das hier gefundene Beispiel hier in VS2010 einzufügen:

%Vor%

Dies wird im Veröffentlichungsmodus gut kompiliert, aber im Debug-Modus wird es nicht kompilieren. Der Grund dafür ist, dass die Implementierung im Debug-Modus überprüft, ob der Iteratorbereich bereits sortiert ist, und dabei das gegebene Prädikat verwendet:

%Vor%

Das ruft auf:

%Vor%

Außer, dass in meinem Fall kein operator() sowohl das linke als auch das rechte "S" Argument nehmen kann. Also, gibt es einen Fehler in der Visual-Implementierung? Oder soll das ursprüngliche Beispiel nicht portabel sein? Ich denke, ich könnte es schaffen, indem es eine dritte Operator () - Überladung bietet, aber es scheint, dass es ohne

funktionieren sollte

Danke

    
lezebulon 12.09.2013, 15:01
quelle

5 Antworten

12

Nichts im Standard erfordert, dass der Komparator mit zwei Objekten aus dem Bereich aufrufbar ist. Das ist also ein Fehler in der von VS 2010 verwendeten Standardbibliothek.

Hier sind alle relevanten Anforderungen (Zitat C ++ 11):

[lower.bound] §1 + 2:

  

1 Benötigt: Die Elemente e von [first,last) müssen in Bezug auf den Ausdruck ... comp(e, value) partitioniert sein.

     

2 Rückgabewert: Der letzte Iterator i im Bereich [first,last] , so dass für jeden Iterator j im Bereich [first,i) die folgenden entsprechenden Bedingungen gelten: ... comp(*j, value) != false .

[oberer.bound] §1 + 2:

  

1 Benötigt: Die Elemente e von [first,last) müssen in Bezug auf den Ausdruck ... !comp(value, e) partitioniert sein.

     

2 Rückgabewert: Der letzte Iterator i im Bereich [first,last] , so dass für jeden Iterator j im Bereich [first,i) die folgenden entsprechenden Bedingungen gelten: ... comp(value, *j) == false .

[equal.range] §1 + 2:

  

1 Voraussetzung: Die Elemente e von [first,last) müssen in Bezug auf die Ausdrücke ... comp(e, value) und !comp(value, e) partitioniert sein. Auch für alle Elemente e von [first, last) , ... comp(e, value) bedeutet !comp(value, e) .

     

2 Rückgabe:

     

...

%Vor%

(Die Ellipsen sind für die Version ohne Vergleicher).

    
Angew 12.09.2013, 15:08
quelle
2

Angew hat bereits den Standard zitiert und darauf hingewiesen, dass VS fehlerhaft ist. Ich möchte nur betonen, dass VS2010 hier zwei Bugs hat (im Debug-Modus):

  1. Es wird versucht, Compare::operator(_Ty1, _Ty2) zu verwenden, das vom Standard nicht benötigt wird. Dieser bekannte Fehler wurde von Angew hervorgehoben und durch Bens Kommentar hervorgehoben.

  2. Er prüft, ob der Eingabebereich sortiert ist, was auch vom Standard nicht gefordert wird. Dies ist ein weit ernsthafterer Fehler, da er die Verwendbarkeit von equal_range reduziert und im schlimmsten Fall eine vollständige Sortierung des Bereichs erfordert, auch wenn dies nicht algorithmisch notwendig war. Vielleicht kann jemand einen Fehlerbericht an MS senden?

Beachten Sie, dass der erste Fehler nur eine Konsequenz (in der Implementierung von equal_range ) des zweiten Fehlers ist. Vermutlich ist der Eingabebereich für die meisten Anwendungen bereits sortiert, teilweise weil der Benutzer unnötigerweise sortiert hat (was zeigt, dass Fehler in der MS-Bibliothek zu schlechtem Benutzercode führen), und die Bereitstellung eines zusätzlichen Vergleichsoperators behebt das Problem (Was die Frage der OP betrifft).

    
Walter 12.09.2013 16:35
quelle
1

[lib.equal.range] sagt:

  

Benötigt: T ist LessThanComparable (20.1.2).

und

  

Effekte: Findet den größten Teilbereich [i, j), so dass der Wert sein kann   bei jedem Iterator k eingefügt, ohne die Reihenfolge zu verletzen. k   erfüllt die entsprechenden Bedingungen:! (* k & lt; Wert) & amp; & amp; ! (Wert & lt; * k)   oder comp (* k, Wert) == false & amp; & amp; comp (Wert, * k) == falsch.

Ihr Code erfüllt beide Bedingungen und sollte gut kompiliert werden, was bedeutet, dass es ein Fehler in Visual Studio ist.

    
BЈовић 12.09.2013 15:23
quelle
1

Als allgemeine Antwort. Jeder Compiler und jede Standardbibliothek haben Macken und Stellen, an denen sie den Standard nicht richtig implementieren. Dies bedeutet, dass, wenn der Code nicht auf einer anderen Plattform getestet wird, immer die Möglichkeit besteht, dass geringfügige Änderungen erforderlich sind.

Auf der positiven Seite, wenn man versucht, den Standard einzuhalten, sollten diese Änderungen sehr gering sein.

    
doron 12.09.2013 15:31
quelle
-1

Damit der gleiche Bereich korrekt funktioniert, muss der Bereich sortiert werden. Ich denke, der VS-Compiler versucht zu sagen, dass Ihre Absicht falsch ist, vielleicht?

    
Coder777 12.09.2013 15:15
quelle

Tags und Links