Al momento sto imparando il C ++ e cerco di evitare di prendere cattive abitudini. Da quello che ho capito, clang-tidy contiene molte "best practice" e cerco di rispettarle nel miglior modo possibile (anche se non capisco necessariamente perché siano ancora considerate buone), ma non sono sicuro se capire cosa è consigliato qui.
Ho usato questa classe dal tutorial:
class Creature
{
private:
std::string m_name;
public:
Creature(const std::string &name)
: m_name{name}
{
}
};
Questo porta a un suggerimento da parte di clang-tidy che dovrei passare per valore invece di riferimento e utilizzare std::move. Se lo faccio, ricevo il suggerimento di fare nameun riferimento (per assicurarmi che non venga copiato ogni volta) e l'avviso che std::movenon avrà alcun effetto perchéname è un constquindi dovrei rimuoverlo.
L'unico modo in cui non ricevo un avviso è rimuovere del consttutto:
Creature(std::string name)
: m_name{std::move(name)}
{
}
Il che sembra logico, poiché l'unico vantaggio di constera evitare di fare confusione con la stringa originale (cosa che non accade perché ho passato per valore). Ma ho letto su CPlusPlus.com :
Sebbene si noti che -nella libreria standard- lo spostamento implica che l'oggetto spostato-da sia lasciato in uno stato valido ma non specificato. Ciò significa che, dopo tale operazione, il valore dell'oggetto spostato deve essere solo distrutto o assegnato a un nuovo valore; accedendovi altrimenti si ottiene un valore non specificato.
Ora immagina questo codice:
std::string nameString("Alex");
Creature c(nameString);
Poiché nameStringviene passato per valore, std::moveinvaliderà solo nameall'interno del costruttore e non toccherà la stringa originale. Ma quali sono i vantaggi di questo? Sembra che il contenuto venga copiato solo una volta, comunque, se passo per riferimento quando chiamom_name{name} , se passo per valore quando lo passo (e poi viene spostato). Capisco che questo è meglio che passare per valore e non usare std::move(perché viene copiato due volte).
Quindi due domande:
- Ho capito bene cosa sta succedendo qui?
- C'è qualche vantaggio nell'usare
std::moveil passaggio per riferimento e solo per chiamarem_name{name}?
std::string_viewe l'SSO.
clang-tidyè un ottimo modo per farmi ossessionare da microottimizzazioni non necessarie a scapito della leggibilità. La domanda da porsi qui, prima di ogni altra cosa, è quante volte chiamiamo effettivamente il Creaturecostruttore.
Creature c("John");crea una copia extra