Home > Backend Development > C++ > How to Correctly Initialize a Vector with Move-Only Types in C ?

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

DDD
Release: 2024-12-17 16:06:11
Original
840 people have browsed it

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

Vector Initialization with Move-Only Types

Consider the following code, which aims to initialize a vector with std::unique_ptr instances:

#include <vector>
#include <memory>

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

However, this code triggers an error during compilation in GCC 4.7, as std::unique_ptr does not support copying, and the compiler attempts to create copies of the pointers during initialization.

GCC's Behavior

GCC's attempt to copy the pointers can be considered correct under the current C standard, which does not explicitly address list-initialization scenarios for move-only types like unique_ptr.

Alternative Initialization Methods

To properly initialize a vector with move-only types, one can employ the following approaches:

Using Iterators:

This approach involves creating a move iterator for the initializer list and passing it to the vector's constructor:

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

Using rref_wrapper:

This technique employs a helper type that provides a temporary storage for move references:

#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());
}
Copy after login

The above is the detailed content of How to Correctly Initialize a Vector with Move-Only Types in C ?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template