11

簡単な C++11 スタイルのステートフル アロケーター型を作成しました。与えられた

template<typename T> class my_allocator {
   // the usual stuff
};

template<typename T> using my_vector = std::vector<T, my_allocator<T>>;

my_vector<int> x;

std::vector<int> y = x; // error

デフォルトのアロケータを使用しmy_vectorて a から a への変換を許可する最良の方法は何ですか? std::vectorGCC 4.7(最近のsvn)は言う

error: conversion from 'my_vector<int> {aka std::vector<int, my_allocator<int>>}' to non-scalar type 'std::vector<int>' requested

明らかに、これは次のような単純な変換関数で行うことができます。

template<typename T> std::vector<T> to_std_vec(const my_vector<T>& v)  {
   return std::vector<T>(&v[0], &v[v.size()]);
   }

しかし、これはかなり洗練されていないようです。C++11 でより良い解決策はありますか?

もちろん、この状況では移動セマンティクスは適切ですが、余分なノイズやタイピングなしでコピーの構築と代入が機能することを望みます。

4

3 に答える 3

14

明らかなコピーを回避することはおそらく期待できません: std::vector<int> y(x.begin(), x.end();. の要素はyによって割り当てられますがstd::allocator、 の要素はx独自のアロケータによって割り当てられ、破棄されます。2 つのアロケータは、まったく無関係なメモリポインタの概念を持つことができます。あるアロケータが使用するメモリ ストレージが、他のアロケータと何らかの形で関連しているという理由はありません。

では、セマンティック要素のコピーを作成する以外に何ができるでしょうか?

古いコンテナがもう必要ない場合は、moveを実行する必要があります:

std::vector<int> y(std::make_move_iterator(x.begin()),
                   std::make_move_iterator(x.end()));

(これは、要素が同意する独自のアロケーターを持っている場合に役立ちます。もちろんint、ではありません。)

更新:vector<T, Alloc>要点を補強するために、 a の内部データ バッファーはtypeではなく、typeであることに注意してください。これらが 2 つの異なるアロケータに関連する型である理由はありません。T*Alloc::pointer

于 2011-11-19T00:43:14.957 に答える
2

あなたの問題には3つの解決策があります:

I.ベクトル「y」がまだ存在しない場合は、次を使用できます。

std::vector<int> y(x.begin(), x.end());

Ⅱ.ベクトル 'y' が既に存在する場合は、: (クラスのメンバーなど) を使用できます。

this->y.assign(x.begin(), x.end());

ベクトルを埋めるこれらの 2 つの方法は、コンテナーの種類を見ていません。(したがって、アロケータの型)

III. 別の解決策は、std アロケーターと独自のアロケーターの間のアロケーター アダプターとして使用できる親クラスを作成することです。この場合、2 つのアロケーターは同じ型であり、operator=() のようなベクター メソッドで使用できます。

于 2013-01-15T14:56:07.090 に答える
2

うーん、ここでの唯一のオプションは次のような完全なコピーだと思います:

std::vector<int> y( x.begin(), x.end());
于 2011-11-19T00:39:29.453 に答える