C ++ 17 wprowadza [[nodiscard]]
atrybut, który pozwala programistom oznaczać funkcje w taki sposób, że kompilator generuje ostrzeżenie, jeśli zwracany obiekt zostanie odrzucony przez program wywołujący; ten sam atrybut można dodać do całego typu klasy.
Przeczytałem o motywacji tej funkcji w oryginalnej propozycji i wiem, że C ++ 20 doda atrybut do standardowych funkcji, takich jak std::vector::empty
, których nazwy nie przekazują jednoznacznego znaczenia w odniesieniu do wartości zwracanej.
To fajna i przydatna funkcja. W rzeczywistości wydaje się to zbyt przydatne. Gdziekolwiek czytam [[nodiscard]]
, ludzie dyskutują o tym, jakbyś po prostu dodał go do kilku wybranych funkcji lub typów i zapomniał o reszcie. Ale dlaczego wartość nie do odrzucenia powinna być szczególnym przypadkiem, szczególnie podczas pisania nowego kodu? Czy odrzucona wartość zwracana nie jest zazwyczaj błędem lub marnowaniem zasobów?
I czy nie jest jedną z zasad projektowania samego C ++, że kompilator powinien wychwytywać jak najwięcej błędów?
Jeśli tak, to dlaczego nie dodać [[nodiscard]]
własnego, nie-starszego kodu do prawie każdego pojedynczego void
niefunkcji i niemal każdego typu klasy?
Próbowałem to zrobić we własnym kodzie i działa dobrze, ale jest tak strasznie gadatliwy, że zaczyna przypominać Javę. Wydaje się bardziej naturalne, aby kompilatory domyślnie ostrzegały o odrzuconych wartościach zwrotnych, z wyjątkiem kilku innych przypadków, w których zaznaczasz swój zamiar [*] .
Ponieważ widziałem zero dyskusji na temat tej możliwości w standardowych propozycjach, wpisach na blogu, pytaniach dotyczących przepełnienia stosu lub w dowolnym innym miejscu w Internecie, muszę coś przeoczyć.
Dlaczego taka mechanika nie miałaby sensu w nowym kodzie C ++? Czy gadatliwość jest jedynym powodem, aby nie używać [[nodiscard]]
prawie wszędzie?
[*] Teoretycznie możesz [[maydiscard]]
zamiast tego mieć coś w rodzaju atrybutu, który można również dodać z mocą wsteczną do funkcji takich jak printf
w implementacjach biblioteki standardowej.
const
mogą znacznie nadmuchać „prostą” klasę (a raczej „zwykły stary obiekt danych”) w C ++.
std::vector
lub std::unique_ptr
, których potrzebujesz tylko elementów danych w definicji klasy. Pracowałem w obu językach; Java jest dobrym językiem, ale jest bardziej szczegółowy.
operator =
na przykład. Istd::map::insert
…