Wird std :: move auf der Initialisierungsliste des Konstruktors für übergebene Heavy-Member wirklich benötigt?

Kürzlich habe ich ein Beispiel aus gelesencppreference ... / vector / emplace_back:

struct President
{
    std::string name;
    std::string country;
    int year;

    President(std::string p_name, std::string p_country, int p_year)
        : name(std::move(p_name)), country(std::move(p_country)), year(p_year)
    {
        std::cout << "I am being constructed.\n";
    }

Meine Frage: ist dasstd::move wirklich gebraucht? Mein Punkt ist, dass diesp_name wird im Rumpf des Konstruktors nicht verwendet, gibt es also möglicherweise eine Regel in der Sprache, die standardmäßig die Verschiebungssemantik verwendet?

Das wäre wirklich ärgerlich, wenn man jedem Heavy Member std :: move auf der Initialisierungsliste hinzufügt (wie zstd::string, std::vector). Stellen Sie sich Hunderte von KLOC-Projekten vor, die in C ++ 03 geschrieben wurdenstd::move?

Diese Frage:Move-Konstruktor-und-Initialisierungsliste Antwort sagt:

Als goldene Regel gilt, dass Sie immer dann, wenn Sie etwas als rWert-Referenz nehmen, es in std :: move verwenden müssen, und wenn Sie etwas als universelle Referenz nehmen (dh als Templated-Typ mit && abgeleitet), müssen Sie es in std :: verwenden. nach vorne

Ich bin mir aber nicht sicher: Wertübergabe ist eher keine universelle Referenz?

[AKTUALISIEREN]

Um meine Frage klarer zu machen. Können die Konstruktorargumente als XValue behandelt werden - ich meine ablaufende Werte?

In diesem Beispiel verwenden wir AFAIK nichtstd::move:

std::string getName()
{
   std::string local = "Hello SO!";
   return local; // std::move(local) is not needed nor probably correct
}

Wäre es also hier nötig:

void President::setDefaultName()
{
   std::string local = "SO";
   name = local; // std::move OR not std::move?
}

Für mich ist diese lokale Variable eine auslaufende Variable - daher könnte eine Verschiebungssemantik angewendet werden.

Antworten auf die Frage(4)

Ihre Antwort auf die Frage