O C ++ 17 apresenta o [[nodiscard]]
atributo, que permite aos programadores marcar funções de uma maneira que o compilador produza um aviso se o objeto retornado for descartado por um chamador; o mesmo atributo pode ser adicionado a um tipo de classe inteiro.
Eu li sobre a motivação para esse recurso na proposta original e sei que o C ++ 20 adicionará o atributo a funções padrão como std::vector::empty
, cujos nomes não transmitem um significado inequívoco em relação ao valor de retorno.
É um recurso interessante e útil. De fato, quase parece muito útil. Em todos os lugares em que leio [[nodiscard]]
, as pessoas discutem isso como se você apenas o adicionasse a algumas poucas funções ou tipos e esquece o resto. Mas por que um valor não descartável deve ser um caso especial, especialmente ao escrever um novo código? Um valor de retorno descartado não é tipicamente um bug ou pelo menos um desperdício de recursos?
E não é um dos princípios de design do próprio C ++ que o compilador deve capturar o maior número possível de erros?
Se sim, por que não adicionar [[nodiscard]]
seu próprio código não legado a quase todas as não void
funções e quase todos os tipos de classe?
Eu tentei fazer isso no meu próprio código e funciona bem, exceto que é tão detalhado que começa a parecer Java. Parece muito mais natural fazer com que os compiladores avisem sobre valores de retorno descartados por padrão, exceto nos poucos outros casos em que você marca sua intenção [*] .
Como eu vi zero discussões sobre essa possibilidade em propostas padrão, entradas de blog, perguntas sobre estouro de pilha ou em qualquer outro lugar na internet, devo estar perdendo alguma coisa.
Por que essa mecânica não faria sentido no novo código C ++? A verbosidade é a única razão para não usar em [[nodiscard]]
quase todos os lugares?
[*] Em teoria, você pode ter algo como um [[maydiscard]]
atributo, que também pode ser adicionado retroativamente a funções como printf
nas implementações da biblioteca padrão.
const
podem inchar uma classe "simples", caso contrário, (ou melhor, "objeto de dados antigo simples") consideravelmente em C ++.
std::vector
ou std::unique_ptr
, das quais você só precisa de membros de dados em sua definição de classe. Eu trabalhei com os dois idiomas; Java é uma linguagem aceitável, mas é mais detalhada.
operator =
por exemplo. Estd::map::insert
.