1

私は単純なポイント構造を持っています

struct mypoint
{
    int x;
    int y;
};

とsvectormypoint

vector<mypoint> myvector;

ポイントのすべてのint座標 (つまり、、、、、、、...) を含むのベクトルを作成したい場合はx1、次の方法で簡単に実行できます。y1x2y2x3y3

vector<mypoint>::iterator pt, ptend(myvector.end());
vector<int> newvector;

for(pt=myvector.begin(); pt!=ptend; ++pt)
{
    newvector.push_back(pt->x);
    newvector.push_back(pt->y);
}

C++11 を使用して、1 行 (または 2 行) のコードで同じ結果を得る方法はありますか?

4

6 に答える 6

4
std::vector<int> extractIntsFromPoints(const std::vector<mypoint>& pointVector)
{
    std::vector<int> retVector;    
    for (const auto& element : pointVector)
    {
        retVector.push_back(element.x);
        retVector.push_back(element.y);
    }
    return retVector;
}

int ベクトルが必要な場所でこの関数を呼び出します。追加の C++11 にするために、範囲ベースの for ループを挿入しました。

于 2013-03-27T15:48:49.107 に答える
3

C++11 を使用しているため、新しい for 構文を使用できます。

vector<int> newvector;

for( const auto &pt : myvector)
{
    newvector.push_back(pt.x);
    newvector.push_back(pt.y);
}
于 2013-03-27T15:47:56.510 に答える
1

投稿から盗みます: C++ std::transform ペアのベクトル -> 最初から新しいベクトルへ

vector<int> items;
std::transform(pairs.begin(), 
               pairs.end(), 
               std::back_inserter(items), 
               [](const std::pair<int, int>& p) { return p.first; });
于 2013-03-27T15:49:55.397 に答える
1

ラムダを使用した約 4 行を次に示します。

vector<mypoint> points;
vector<int> iv;

points.push_back(mypoint(1,2));
points.push_back(mypoint(3,4));
points.push_back(mypoint(5,6));

for_each(points.cbegin(), points.cend(),
    [&iv](const mypoint &pt) {
        iv.push_back(pt.x);
        iv.push_back(pt.y);
    });
于 2013-03-27T15:50:32.467 に答える
1

を使用しstd::pair<>て座標をプッシュしstd::make_pair、次に を次std::pair<>のようなベクトルにプッシュする を使用できます。

mypoint a_point;
std::pair<int, int> point = std::make_pair(a_point.x, a_point.y);
vector<std::pair<int, int>> vec.push_back(point).

おそらくかさばりますが、2 行でうまく機能し、各ポイント軸の大きさを分離してstd::vector.

于 2013-03-27T15:51:12.600 に答える
1

reima が既に述べたように、既存のシーケンスのみを参照したい場合は、キャストmyvector.data()するだけで十分です (ホールドint*を想定)。sizeof(mypoint) == 2 * sizeof(int)ただし、フラット化されたシーケンスのコピーが明示的に必要な場合は、次のような小さなユーティリティ関数を作成する方がよいでしょう。

    template <typename T, typename U>
    std::vector<T> flatten(std::vector<U> const& other) {
        static_assert(std::is_trivially_copyable<U>::value,
                      "source type must be trivially copyable!");
        static_assert(std::is_trivially_copy_constructible<T>::value,
                      "destination type must be trivially copy constructible!");
        static_assert((sizeof(U) / sizeof(T)) * sizeof(T) == sizeof(U),
                      "sizeof(U) must be a multiple of sizeof(T)!");

        return std::vector<T>(reinterpret_cast<T const*>(other.data()),
           reinterpret_cast<T const*>(std::next(other.data(), other.size())));             
    }

    template <typename U>
    std::vector<typename U::value_type> flatten(std::vector<U> const& other) {
         return flatten<typename U::value_type>(other);
    }

コードを

    auto newvector = flatten<int>(myvector);

mypoint structまたは- (STL準拠の)value_typeメンバータイプを装備している場合-

    auto newvector = flatten(myvector);

このユーティリティ関数は、ポインターをポインターreinterpret_castに変換するために本質的に安全ではないコンストラクターを微調整したものにすぎないことに注意してください。の使用に伴う安全上の警告を取り除くために、関数はいくつかのパラシュートを使用します。したがって、これらすべてを別の関数で非表示にすることをお勧めします。それでも、、ムーブ コンストラクション、、タイプ トレイトなどの多くの C++11 機能を使用し、呼び出しサイト コードを最小限に抑えます。mypointintreinterpret_castflattenstatic_assertautostatic_assertstd::nextvector::data()

vectorまた、の範囲コンストラクターはメモリ割り当てと call のみを実行するため、uninitialized_copyこれは非常に効率的memcpyです。

于 2013-03-28T09:53:38.510 に答える