Ποιοι είναι οι κανόνες αναζήτησης ονόματος και απλοποίησης τύπων για τους τύπους επιστροφών στο τέλος;

Ποιοι είναι οι κανόνες αναζήτησης ονόματος και απλοποίησης τύπων για τους τύπους επιστροφών στο τέλος;

IMO, έχεις δύο άσχετες ερωτήσεις εδώ, θα προσπαθήσω να απαντήσω στην πρώτη.
Καλύπτεται από [basic.scope.class]/1.5:

Στον ορισμό εκτός κατηγορίας της συνάρτησης μέλους

auto X::f() -> foo { /* ... */ }

τον τύπος-επιστροφής ακολουθεί το αναγνωριστικό δήλωσης X::f , άρα είναι το πιθανό εύρος για τα μέλη της κλάσης, επομένως η αναζήτηση χωρίς επιφύλαξη βρίσκει το X::foo όταν foo αναφέρεται εκεί.


Για το #1, ανατρέξτε στο C++17 [basic.lookup.qual]/3:

Ένας συνηθισμένος τύπος επιστροφής στην αρχή προηγείται του declarator-id , δηλαδή X::f οπότε εξετάζεται το εύρος του χώρου ονομάτων. Ακολουθεί ένας τύπος επιστροφής που ακολουθεί, επομένως αναζητείται στο πεδίο της τάξης.

Για το #2, παρατηρήστε ότι η σύνταξη για trailing-return-type από το [dcl.decl]/4 είναι:

και σύμφωνα με το [dcl.fct]/2, αυτός ο τύπος είναι ο τύπος επιστροφής της συνάρτησης.

Εάν επρόκειτο να χρησιμοποιήσετε έναν κύριο τύπο επιστροφής, ο προσδιορισμός του τύπου επιστροφής της συνάρτησης θα έπρεπε να καθοριστεί αναδρομικά από το [dcl.fct]/1:

και τον τύπο του περιεχόμενου αναγνωριστικό δήλωσης στη δήλωση T D1 είναι "derived-declarator-type-list T ”, τον τύπο του αναγνωριστικό δήλωσης στο D είναι "derived-declarator-type-list όχι εκτός (opt) συνάρτηση του ( parameter-declaration-clause ) cv-qualifier-seq (opt) ref-qualifier (opt) επιστρέφει T ”, όπου ...

Εδώ, T αντιπροσωπεύει μια decl-specifier-seq . Εάν είχατε ένα typedef-name που υποδήλωνε int(*)(int) , ας πούμε, FPII , τότε θα μπορούσατε απλώς να χρησιμοποιήσετε αυτό:

FPII g(float);

Αλλά αν θέλετε να το κάνετε με τον δύσκολο τρόπο, πρέπει να βρούμε το T και D1 έτσι ώστε όταν ο παράγωγος-δηλωτής-τύπος-λίστα, δηλαδή, η ακολουθία μετασχηματισμών τύπων D1 θα προκαλούσε στο T σύμφωνα με τη συντακτική μορφή του D1 , εφαρμόζονται στη "συνάρτηση του int επιστρέφει T ", το αποτέλεσμα είναι "συνάρτηση του float επιστροφή δείκτη σε (συνάρτηση int επιστρέφει int )".

Αυτό θα ικανοποιηθεί εάν το παράγωγο-declarator-type-list είναι "function of float επιστροφή δείκτη σε", και T είναι int . Ο δηλωτής D1 πρέπει επομένως να έχει τη συντακτική μορφή * αναγνωριστικό δήλωσης (float) προκειμένου να προκύψει ο εν λόγω κατάλογος παραγόμενου-τύπου-δηλωτή. Πρέπει να προσθέσουμε ένα επιπλέον ζεύγος παρενθέσεων για να έχουμε τη σωστή δέσμευση στη συνολική δήλωση.

Δεν υπάρχει "μεταμόρφωση" εδώ από τον τύπο επιστροφής μετάδοσης σε έναν κορυφαίο τύπο επιστροφής. Αντίθετα, ο τύπος επιστροφής μετάδοσης σάς επιτρέπει απλώς να καθορίσετε τον τύπο επιστροφής απευθείας, ενώ ο κύριος τύπος επιστροφής ερμηνεύεται από αυτόν τον αλγόριθμο επαναλαμβανόμενης αναδίπλωσης του δηλωτή. Αν και αυτό είναι λογικό σύμφωνα με την αρχή της «δήλωσης ακολουθεί τη χρήση», τείνει να είναι λίγο δύσκολο για τους ανθρώπους να το κατανοήσουν διαισθητικά, συμπεριλαμβανομένων των πολύ έμπειρων προγραμματιστών C++. Και ειδικά όταν πρέπει να το κάνουμε αντίστροφα (γράψτε τη δήλωση, αντί να ερμηνεύσετε μια υπάρχουσα).