ホームページ > バックエンド開発 > C++ > C で移動のみの型を使用してベクトルを初期化するにはどうすればよいですか?

C で移動のみの型を使用してベクトルを初期化するにはどうすればよいですか?

Linda Hamilton
リリース: 2025-01-01 08:55:09
オリジナル
873 人が閲覧しました

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

移動のみの型を使用したベクトルの初期化は達成できますか?

一意のポインタ、つまり移動を使用してベクトルを初期化しようとするときに疑問が生じます。 -専用タイプ。次のようなコードに遭遇すると、

#include <vector>
#include <memory>

using move_only = std::unique_ptr<int>;
std::vector<move_only> v { move_only(), move_only(), move_only() };
ログイン後にコピー

GCC 4.7 は初期化子リストから一意のポインターをコピーしようとします。その結果、 std::unique_ptr の移動専用の性質により、コピー試行は許可されません。 .

GCC のアプローチ: そうですか欠陥?

一意のポインタがコピーできないことを考慮すると、ポインタをコピーするという GCC の意図は正しいです。ただし、初期化子リストからコピーする方法では、削除されたコピー コンストラクターがトリガーされます。

Make Move Iterator を使用する代替解決策

次の移動専用型を処理するにはベクトルの初期化の場合、推奨されるアプローチには、make move イテレータを利用することが含まれます。

#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))};
}
ログイン後にコピー

make move から取得されるイテレータイテレータは逆参照時の要素の移動を容易にし、コピーの問題を解決します。

テンプレート ラッパーを使用した代替解決策

もう 1 つのアプローチには、右辺値参照セマンティクスを備えたテンプレート ラッパーを使用することが含まれます。

// 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;
ログイン後にコピー

このソリューションは、概念的に右辺値を次の値に変換する方法を提供します。 lvalue は変動するため、注意が必要です。より簡潔な初期化は、次の 2 段階のプロセスを通じて実現できます:

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());
ログイン後にコピー

以上がC で移動のみの型を使用してベクトルを初期化するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート