ホームページ >バックエンド開発 >C++ >リスト初期化は C の移動専用型のベクトルを正しく処理できますか?

リスト初期化は C の移動専用型のベクトルを正しく処理できますか?

DDD
DDDオリジナル
2024-12-24 16:41:14915ブラウズ

Can List-Initialization Correctly Handle Vectors of Move-Only Types in C  ?

移動のみ型のベクトルでリスト初期化を使用できますか?

list-initialization 構文では、GCC は unique_pointers をベクトルにコピーしようとします。この動作は、 unique_ptrs がコピー可能ではないという事実に起因しています。

ポインタをコピーしようとする GCC は正しいですか?

この場合の GCC の動作は正しくありません。 unique_ptrs のベクトルは、ポインターをコピーして構築することはできません。代わりに、移動セマンティクスを使用する必要があります。

代替解決策

移動専用型のベクトルを適切に初期化するには、std::make_move_iterator を使用して指定された要素を移動する反復子を作成します。 dereferenced:

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

追加のアプローチ

それほど単純ではありませんが、std::enable_if とヘルパー構造体 rref_wrapper を使用して move のベクトルを構築する別の方法もあります。 -only タイプ:

#include <utility>
#include <type_traits>

template<class T>
struct rref_wrapper
{ // CAUTION - very volatile, use with care
  explicit rref_wrapper(T&amp;&amp; v)
    : _val(std::move(v)) {}

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

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

// only usable on temporaries
template<class T>
typename std::enable_if<
  !std::is_lvalue_reference<T>::value,
  rref_wrapper<T>
>::type rref(T&amp;&amp; v){
  return rref_wrapper<T>(std::move(v));
}

// lvalue reference can go away
template<class T>
void rref(T&amp;) = delete;

このヘルパーを使用すると、ベクターは次のことができます。

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

このアプローチでは std::enable_if を利用して、rref が一時的にのみ使用できるようにし、潜在的な誤用を防ぎます。

以上がリスト初期化は C の移動専用型のベクトルを正しく処理できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。