4

次のような配列がある場合:

struct S {... };

S m_aArr[256];

これを使用して、次のようなベクトルを構築したいと思います。

std::vector<S*> m_vecS;

ループしてプッシュバックするのではなく、これを行う方法はあります&m_aArr[i]か? ベクトルはポインターの 1 つであり、元の配列はオブジェクトの 1 つであり、メモリのブロックを渡すことはできないため、配列に対してstd::beginandを使用する従来の方法を使用できないことを理解しています。std::end

4

3 に答える 3

12

標準ライブラリを使用して、反復とプッシュバックを行うことができます。

std::transform(std::begin(m_aArr), std::end(m_aArr),
               std::back_inserter(m_vecS), std::addressof<S>);

これにより、関数をm_aArr適用して各要素が変換されます。std::addressof<S>次に、変換された各要素がイテレータによってpush_back取り込まm_vecSれます。std::back_inserter

C++11 より前にこれを行うにはstd::begin、 、std::end、またはstd::addressofにアクセスできないため、次のようになります。

std::transform(m_aArr, m_aArr + 256, std::back_inserter(m_vecS), boost::addressof<S>);

これは を使用しboost::addressofます。

于 2013-04-24T12:16:15.260 に答える
5

std::transformループを実行させることができます:

transform(std::begin(a), std::end(a), std::back_inserter(v), 
          [] (S& s) { return &s; });

関数名はADLstd::transformによって検出されるため、name を完全修飾する必要がないことに注意してください。

これは、その動作をテストするための完全なプログラムです。

#include <iostream>
#include <vector>
#include <algorithm> // <== Required for std::transform
#include <iterator>  // <== Required for std::back_inserter, std::begin, std::end

struct S
{
    S() : i(0) { }
    S(int i_) : i(i_) { }
    int i;
};

int main()
{
    S a[256] = { 42 }; // Copy-initializes first element from 42,
                       // default-constructs all other elements

    std::vector<S*> v;
    transform(std::begin(a), std::end(a), std::back_inserter(v), 
              [] (S& s) { return &s; });

    std::cout << v.size() << std::endl; // Prints 256
    std::cout << v[0]->i << std::endl; // Prints 42
    std::cout << v[1]->i << std::endl; // Prints 0
}

そして、これがライブの例です。

于 2013-04-24T12:16:35.673 に答える
1

潜在的に複数の via ではなくstd::generate_n()、単一の割り当てを実行することを使用したソリューション:std::vectorstd::vector::push_back()

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

int main()
{
    struct S {};
    S a[128];
    S* ap = a;

    std::vector<S*> v(sizeof(a)/sizeof(a[0]));
    std::generate_n(std::begin(v), v.size(), [&]() { return ap++; });

    for (size_t i = 0; i < v.size(); i++)
    {
        if (&a[i] != v[i]) // Ensure same address at each element.
        {
            std::cerr << "Error\n";
            break;
        }
    }
    return 0;
}

http://ideone.com/73nKSTでオンラインを参照してください。

于 2013-04-24T12:27:43.730 に答える