overload - operator() c++




In che modo l'operatore di confronto a tre vie è diverso dalla sottrazione? (2)

Ci sono alcune risposte significative qui sulla differenza, ma Herb Sutter nel suo articolo dice specificamente:

<=> è per gli implementatori di tipi: il codice utente (incluso il codice generico) al di fuori dell'implementazione di un operatore <=> non dovrebbe quasi mai invocare un <=> direttamente (come già scoperto come una buona pratica in altre lingue);

Quindi, anche se non ci fosse differenza, il punto dell'operatore è diverso: aiutare gli scrittori di classe a generare operatori di confronto.

La differenza fondamentale tra l'operatore di sottrazione e l'operatore "astronave" (secondo la proposta di Sutter) è che l' operator- sovraccarico ti dà un operatore di sottrazione, mentre l' operator<=> sovraccarico operator<=> :

  • ti dà i 6 operatori di confronto principali (anche se dichiari l'operatore come default : nessun codice da scrivere!);
  • dichiara se la tua classe è comparabile, ordinabile e se l'ordine è totale o parziale (forte / debole nella proposta di Sutter);
  • consente confronti eterogenei: puoi sovraccaricarlo per confrontare la tua classe con qualsiasi altro tipo.

Altre differenze sono nel valore di ritorno: l' operator<=> restituisce un enum di una classe, la classe specifica se il tipo è ordinabile e se l'ordinamento è forte o debole. Il valore restituito verrebbe convertito in -1, 0 o 1 (anche se Sutter lascia spazio al tipo restituito per indicare anche la distanza, come fa strcmp ). In ogni caso, assumendo il valore di ritorno -1, 0, 1, avremo finalmente una vera funzione signum in C ++ ! ( signum(x) == x<=>0 )

C'è un nuovo operatore di confronto <=> in C ++ 20. Tuttavia, penso che nella maggior parte dei casi una semplice sottrazione funzioni bene:

int my_strcmp(const char *a, const char *b) {
    while (*a == *b && *a != 0 && *b != 0) {
        a++, b++;
    }
    // Version 1
    return *a - *b;
    // Version 2
    return *a <=> *b;
    // Version 3
    return ((*a > *b) - (*a < *b));
}

Hanno lo stesso effetto. Non riesco davvero a capire la differenza.


Ecco alcuni casi per i quali la sottrazione non funziona:

  1. tipi unsigned .
  2. Operandi che causano overflow di numeri interi.
  3. Tipi definiti dall'utente che non definiscono l' operator - (forse perché non è significativo - si può definire un ordine senza definire una nozione di distanza).

Sospetto che questo elenco non sia esaustivo.

Naturalmente, si possono trovare soluzioni alternative per almeno il n. 1 e il n. 2. Ma l'intento operator <=> è incapsulare quella bruttezza.





spaceship-operator