Heim > Backend-Entwicklung > C++ > Wie kann ich einen Vektor mit Nur-Verschieben-Typen in C initialisieren?

Wie kann ich einen Vektor mit Nur-Verschieben-Typen in C initialisieren?

Linda Hamilton
Freigeben: 2025-01-01 08:55:09
Original
871 Leute haben es durchsucht

How Can I Initialize a Vector with Move-Only Types in C  ?

Kann eine Vektorinitialisierung mit Nur-Verschieben-Typen erreicht werden?

Die Frage stellt sich, wenn versucht wird, einen Vektor mit eindeutigen Zeigern, einem Verschieben, zu initialisieren -nur Typ. Wenn Sie auf Code wie diesen stoßen:

#include <vector>
#include <memory>

using move_only = std::unique_ptr<int>;
std::vector<move_only> v { move_only(), move_only(), move_only() };
Nach dem Login kopieren

GCC 4.7 versucht, die eindeutigen Zeiger aus der Initialisierungsliste zu kopieren, was zu einem Kopierversuch führt, der aufgrund der reinen Verschiebungsnatur von std::unique_ptr nicht zulässig ist .

GCCs Ansatz: Ist es so? Fehlerhaft?

Die Absicht von GCC, die Zeiger zu kopieren, ist richtig, wenn man bedenkt, dass eindeutige Zeiger nicht kopierbar sind. Die verwendete Methode, das Kopieren aus der Initialisierungsliste, löst jedoch den Konstruktor für gelöschte Kopien aus.

Alternative Lösung mit Make Move Iterator

Zur Verarbeitung reiner Verschiebungstypen Bei der Vektorinitialisierung besteht ein bevorzugter Ansatz in der Verwendung von Make-Move-Iteratoren:

#include <iterator>
#include <vector>
#include <memory>

int main(){
  using move_only = std::unique_ptr<int>;
  move_only init[] = { move_only(), move_only(), move_only() };
  std::vector<move_only> v{std::make_move_iterator(std::begin(init)),
      std::make_move_iterator(std::end(init))};
}
Nach dem Login kopieren

Die von Make-Move-Iteratoren erhaltenen Iteratoren erleichtern die Bewegung von Elementen bei der Dereferenzierung, wodurch das Problem beim Kopieren gelöst wird.

Alternative Lösung mit Template-Wrappern

Ein anderer Ansatz beinhaltet die Verwendung von Template-Wrappern mit R-Wert-Referenzsemantik:

// Helper type for converting rvalues to lvalues
template<class T>
struct rref_wrapper
{
  explicit rref_wrapper(T&& v)
    : _val(std::move(v)) {}

  explicit operator T() const{
    return T{ std::move(_val) };
  }

private:
  T&amp;&amp; _val;
};

// Helper function to convert rvalues to rref_wrappers
template<class T>
typename std::enable_if<
  !std::is_lvalue_reference<T>::value,
  rref_wrapper<T>
>::type rref(T&& v){
  return rref_wrapper<T>(std::move(v));
}

// Helper function to delete lvalue references
template<class T>
void rref(T&amp;) = delete;
Nach dem Login kopieren

Obwohl diese Lösung eine Möglichkeit zur konzeptionellen Konvertierung von R-Werten in L-Werte bietet, ist sie von entscheidender Bedeutung Aufgrund der Volatilität ist Vorsicht geboten. Eine präzisere Initialisierung kann durch einen zweistufigen Prozess erreicht werden:

std::initializer_list<rref_wrapper<move_only>> il{ rref(move_only()),
                                                   rref(move_only()),
                                                   rref(move_only()) };
std::vector<move_only> v(il.begin(), il.end());
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonWie kann ich einen Vektor mit Nur-Verschieben-Typen in C initialisieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage