2011-08-30 6 views
3

私はオブジェクトのベクトルを持っています。各オブジェクトには、コピー不可オブジェクト(boost::signal)へのboost::shared_ptrがあります。オブジェクトのデフォルトコンストラクタはboost :: signalオブジェクトを作成します。 X個々のオブジェクトを含むように私のベクトルを設定するには一意のオブジェクトを持つstd :: vectorのサイズを変更するには

struct FuncRef 
{ 
    typedef boost::signal0<void, > Func; 
    boost::shared_ptr <Func> function; 
    FuncRef(): 
     function(new Func) 
    { 
    } 
}; 

、私はこれでした: - それは一つのオブジェクトを作るために、既定のコンストラクタを使用していますので、これは、私が期待したものやらなかった

vec.resize(X); 

をし、複製コンストラクタを使用して複製を作成します。私はXオブジェクトになりますが、それらはすべて同じboost::signal0オブジェクトを指しています。

forループでpush_backを使用するよりも簡単に正しいベクターを構築する方法はありますか?

+0

コンパイル時にこのようなエラーを検出するには、クラスに 'boost :: noncopyable'を継承させることができます。 –

+0

@Bjorn - クラスはベクター内にあるので、コピー可能でなければなりません。だから私はshared_ptrを使う必要があります。問題は、それが私にそれを期待していないときにコピーを使用しているということです... – Roddy

+0

正直、私は何を考えていましたか? –

答えて

3

私は考えることができる唯一の方法は、ベクターは、(@ジョナサンは答えとして)必要なメモリを割り当てる作るためにreserveを使用することです。 nが大きい場合、それはおそらく高速ですが、

FuncRef makeFuncRef() { 
    return FuncRef(); 
} 

vec.reserve(vec.size() + n); 
std::generate(std::back_inserter(vec), n, makeFuncRef); 

reserveは、このアプローチには必要ありません:あなたは要素を追加するstd::back_inserterで使用generate_nができます。

1

私は考えることができる最も簡単な方法は一つだけ割り当てがvectorによって必要とされるように、事前にメモリを確保することです。そして、

vec.reserve(X); 

ループとpush_back()。それはあなたのニーズに十分ではありませんか?

+0

はい、それはうまくいきましたが、シンプルな1本のライナーが欠けていたのではないかと思っていました... – Roddy

+0

Björnは 'std :: generate()'と適切なアイデアを持っています。ベクトルの要素*を*に初期化したいかどうかは不明です。それらはある値を保持する必要があります(または未定義です)。 –

+0

は、コードでFuncRefコンストラクタshwonを使用して、デフォルトで構築されたオブジェクトに初期化されます。 Bjornのコードはそのまま動作しますが、ループのためにIMOが読みやすくなります。ラムダをロールすると... – Roddy

0

実際のコピーセマンティクスでコピーコンストラクタ/コピー割り当てを実装できませんか?あなたがベクトル充填で深刻なパフォーマンスを持っていない限り、これは最も明白な解決策のようです。

関連する問題