C ++ 17 introduce l' [[nodiscard]]
attributo, che consente ai programmatori di contrassegnare le funzioni in modo tale che il compilatore produca un avviso se l'oggetto restituito viene scartato da un chiamante; lo stesso attributo può essere aggiunto a un intero tipo di classe.
Ho letto la motivazione di questa funzionalità nella proposta originale e so che C ++ 20 aggiungerà l'attributo a funzioni standard come std::vector::empty
, i cui nomi non trasmettono un significato inequivocabile per quanto riguarda il valore restituito.
È una funzionalità interessante e utile. In effetti, sembra quasi troppo utile. Ovunque io legga [[nodiscard]]
, le persone ne discutono come se lo aggiungessi a poche funzioni o tipi selezionati e dimentichino il resto. Ma perché un valore non scartabile dovrebbe essere un caso speciale, specialmente quando si scrive un nuovo codice? Un valore di ritorno scartato non è in genere un bug o almeno uno spreco di risorse?
E non è uno dei principi di progettazione del C ++ stesso che il compilatore dovrebbe rilevare quanti più errori possibile?
Se è così, allora perché non aggiungere [[nodiscard]]
il proprio codice non legacy a quasi ogni singola non void
funzione e quasi ogni singolo tipo di classe?
Ho provato a farlo nel mio codice, e funziona benissimo, tranne che è così terribilmente dettagliato che inizia a sembrare Java. Sembrerebbe molto più naturale fare in modo che i compilatori avvertano dei valori di ritorno scartati per impostazione predefinita, tranne per i pochi altri casi in cui si contrassegna la propria intenzione [*] .
Dato che ho visto zero discussioni su questa possibilità in proposte standard, post di blog, domande Stack Overflow o in qualsiasi altra parte di Internet, mi devo perdere qualcosa.
Perché tali meccanismi non avrebbero senso nel nuovo codice C ++? La verbosità è l'unica ragione per non usarla [[nodiscard]]
quasi ovunque?
[*] In teoria, potresti avere qualcosa come un [[maydiscard]]
attributo, che potrebbe anche essere aggiunto retroattivamente a funzioni come printf
nelle implementazioni di librerie standard.
const
possono gonfiare una classe altrimenti "semplice" (o piuttosto "semplice oggetto di dati vecchi") considerevolmente in C ++.
std::vector
o std::unique_ptr
, di cui hai solo bisogno di membri di dati nella definizione della classe. Ho lavorato con entrambe le lingue; Java è un linguaggio okay, ma è più dettagliato.
operator =
per esempio. Estd::map::insert
.