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

Wie initialisiere ich einen Vektor mit Nur-Verschieben-Typen in C korrekt?

DDD
DDDOriginal
2024-12-17 16:06:11890Durchsuche

How to Correctly Initialize a Vector with Move-Only Types in C  ?

Vektorinitialisierung mit Nur-Verschieben-Typen

Betrachten Sie den folgenden Code, der darauf abzielt, einen Vektor mit std::unique_ptr-Instanzen zu initialisieren:

#include <vector>
#include <memory>

int main() {
  using move_only = std::unique_ptr<int>;
  std::vector<move_only> v{move_only(), move_only(), move_only()};
}

Dieser Code löst jedoch einen Fehler während der Kompilierung in GCC 4.7 aus std::unique_ptr unterstützt kein Kopieren und der Compiler versucht, während der Initialisierung Kopien der Zeiger zu erstellen.

Verhalten von GCC

Der Versuch von GCC, die Zeiger zu kopieren, kann sein wird nach dem aktuellen C-Standard als korrekt angesehen, der Listeninitialisierungsszenarien für Nur-Verschiebungstypen wie z. B. nicht explizit anspricht unique_ptr.

Alternative Initialisierungsmethoden

Um einen Vektor mit Nur-Verschiebungs-Typen ordnungsgemäß zu initialisieren, können die folgenden Ansätze verwendet werden:

Verwenden von Iteratoren:

Dieser Ansatz beinhaltet das Erstellen und Übergeben eines Verschiebungsiterators für die Initialisierungsliste an den Konstruktor des Vektors:

#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))};
}

Verwenden von rref_wrapper:

Diese Technik verwendet einen Hilfstyp, der einen temporären Speicher für Verschiebungsreferenzen bereitstellt:

#include <utility>
#include <type_traits>

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&& _val;
};

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));
}

template<class T>
void rref(T&) = delete;

int main() {
  using move_only = std::unique_ptr<int>;
  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());
}

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

Stellungnahme:
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