2015-05-20 6 views
5

Podczas wyszukiwania skojarzeń operatorów na Wikipedii zauważyłem, że delete ma związek z prawem na lewo. Źródło jest cytowane jako msdn, sprawdziłem to i jest ono pod priorytetem grupy 3, od prawej do lewej. Więc sprawdziłem the C++ standard (n4296)Operator delete associativity

5.3 wyrażenia Jednoargumentowe [expr.unary]

1) Wyrażenia z jednoargumentowego operatorów grupy prawej do lewej

unary-expression: 
    postfix-expression 
    ++ cast-expression 
    -- cast-expression 
    unary-operator cast-expression 
    sizeof unary-expression 
    sizeof (type-id) 
    sizeof ... (identifier) 
    alignof (type-id) 
    noexcept-expression 
    new-expression 
    delete-expression 
unary-operator: one of 
    * & + - ! ~ 

Jakie implikacje to ma ? Co oznacza, że ​​delete ma w ogóle jakieś powiązanie?

+1

delete * ++ x; Co zrobić, jeśli wskaźnik do wskaźnika znajduje się przed wskaźnikiem, który chcesz usunąć? (skradziony z MickLH) – Almo

Odpowiedz

6

Jak powiedział Barry, pierwszeństwo określa gramatyka (i jest kilka operatorów, którzy nie pasują do podstawowej koncepcji pierwszeństwa, więc można tylko dowiedzieć się, co dzieje się całkowicie poprawnie z gramatyki, nie tabela pierwszeństwa).

Nawet jeśli zignorujemy to, jednak pierwszeństwo usunięcia tylko (przynajmniej zwykle) określa, czy oświadczenie jest zgodne z prawem/dozwolone, a nie co to znaczy. Aby dać kontrprzykład, z + i *, pierwszeństwo określa, że ​​2 * 3 + 4 daje 10 zamiast 14 (to jest mnożenie ma pierwszeństwo).

W przypadku delete w wyniku oświadczenia delete nie jest tworzona żadna wartość, dlatego po prostu instrukcja taka jak delete x + y; jest niedozwolona. Zostałby przeanalizowany jako (delete x) + y;, ale ponieważ delete x nie wytwarza wartości, którą można dodać do czegokolwiek innego, wynik jest zawsze zabroniony (a jeśli zmienisz operatora, pozostanie on prawdziwy).

Łączność nie ma większego sensu dla delete. W szczególności asocjacja dotyczy tego, czy coś takiego: a @ b @ c będzie przetwarzane jako (a @ b) @ c lub a @ (b @ c) (gdzie @ to jakiś operator). Ma to znaczenie tylko dla operatorów, którzy przyjmują dwa operandy. Po prostu nie można łączyć delete s w sposób, który pozwala zadać pytanie (s), na które odpowiada odpowiedź.

+0

To właśnie myślałem; to po prostu nie ma sensu, żeby miało to związek z innymi! Zastanawiałem się, czy brakowało mi czegoś, co dało z tego pożytek. – OMGtechy

2

Standard C++ zazwyczaj nie definiuje operatorów w kategoriach pierwszeństwa lub asocjatywności. Definiuje je pod względem gramatyki. Od [expr.delete] delete jest używany w usuwać ekspresji który jest zdefiniowany jako:

usuwać ekspresji:
        :: zdecydować deletelanego ekspresji
        :: opt delete []cast-expression

przypadku odlewu ekspresji jest zdefiniowana w [expr.cast]

wylewanym wyrażeniem:
        jednoargumentowy ekspresji
        (identyfikator typu)lanego wyrażenie

I jednoskładnikowa ekspresja jest cała masa rzeczy określonych [expr.unary], które są wszystkie wyrażenia unarne (przyrosty, ubytki, delete s siebie)

Oznacza to, że delete *x jest prawostronnie stowarzyszona, ponieważ (delete (*x)) jest jedynym sposobem analizowania tego wyrażenia zgodnie z gramatyką.

Jest to również powód, dla którego cppreference powołuje się na precedens, w którym ma on bezpośredni skutek.Na przykład, delete jest wyższa niż + ponieważ w wyrażeniu tak:

delete x+y 

x+y nie jest jednoskładnikowa ekspresja, więc jedynym prawowitym parsowania gramatyki byłoby (delete x) + y.

+2

Pierwszeństwo nie ma związku z asocjatywnością. –

+0

Właśnie znalazłem to w standardzie, patrz aktualizacja – OMGtechy

1

Skojarzenie dotyczy tego, czy a op b op c jest analizowany jako (a op b) op c lub a op (b op c).

delete to operator jednoargumentowy, więc nie może się z nim kojarzyć. Nie ma powiązania.

I delete delete x nigdy nie jest ważna.