5

「素朴な」解決策は次のとおりです。

std::vector<T> vector_of_objects;
vector_of_objects.reserve(vector_of_pointers.size());
for (T const * p : vector_of_pointers)
    vector_of_objects.push_back(*p);

上記は扱いにくいようで、すぐにはわからないかもしれません。

少なくとも大幅に効率が低下せず、おそらくもう少し速くて直感的なソリューションはありますか? C++11には、私が気付いていない解決策があるかもしれないと思っています...

4

6 に答える 6

8

Does writing everything in one line mean shorter code? No.

In my opinion these two lines are shorter and more readable:

for (auto p : vector_of_pointers)

    vector_of_objects.emplace_back(*p);

 

Function std::for_each is not shorter than ranged-based loop, sometime it's bigger due to passing lambda expressions.

Function std::transform is even longer than std::for_each, however the word transform is an advantage to find out what's happening in the following.

于 2013-09-27T12:07:02.897 に答える
1

いいえ、ソリューションのように copy-ctor を呼び出す必要があります。それを回避する方法はありません。

于 2013-09-27T11:57:23.423 に答える
0

本当の問題は、他の場所のコードをクリーンアップするために、ある場所に余分なコードを書く価値があるほど頻繁にこれを行っているかどうかということだと私には思えます。

次のようなことを可能にする a を書くことを想像deref_iteratorできます。

std::vector<T> vector_of_objects{
    deref_iterator(std::begin(vector_of_pointers)), 
    deref_iterator(std::end(vector_of_pointers))};

ここで、これが元のループより本当に短いかどうかという問題が残ります。キーストロークの単純な数に関しては、おそらく、あなたが付けた名前に依存するでしょう。読みやすい名前を気にしない場合は、次のようになります。

vector<T> v_o{d(begin(v_p)), d(end(v_p))};

短い名前は明らかにそれを短くしますが、私は確かにそれらにアドバイスしません-これを入力しただけでなければ、それが何を意味するのかまったくわかりません. 名前を長くすると (数回繰り返す必要があります)、明らかにキーストロークが増えますが、読みやすさに価値がないと考える人は誰もいないと思います。

いずれにせよ、deref_iteratorそれ自体が明らかに何らかのコードを占有します。イテレータには、通常約 100 行程度のコードを必要とする十分な定型文があります。これを使用するたびに 1 行のコードを節約できると (やや恣意的に) 決めましょう。それを踏まえると、100回使用すると損益分岐点になります。

コード全体を特徴付ける上でそれが正確かどうかはわかりません。イテレータのコードはほとんどがボイラープレートであり、タイプミスを除けば、実際に問題が発生する可能性はあまりありません。ほとんどの場合、適切なヘッダーを含めてそれを使用するだけで済み、実質的にイテレーター自体のコードを確認する必要はありません。

だとすれば、コードの総行数が増えたとしても、改善として受け入れるかもしれません。1回だけ使用するように書くのは明らかに損ですが、損益分岐点となるために100回も必要ないと思います。

于 2013-09-27T14:38:20.093 に答える