4
\$\begingroup\$

This little function can make object creation much easier. Sometimes you need to switch between representing your data as objects vs. having the members in separate containers.

Example:

class Foo {
public:
    Foo(int a_, double b_): a(a_), b(b_){}

    int a;
    double b;
};

And then:

std::vector<int> as = {1,2,3,4,5};
std::vector<double> bs = {6.0,7.0,8.0,9.0,10.0};
std::vector<Foo> foos = zipConstruct<Foo>(as, bs);

cout << foos[3].a << ", " << foos[3].b << endl; // 4, 9

Using:

template <typename T, typename... Arg>
std::vector<T> zipConstruct(std::vector<Arg> const&... argVec)
{
    std::vector<size_t> sizes = {argVec.size()...};
    assert(std::all_of(sizes.begin(), sizes.end(), [&](size_t s){return s=sizes[0];}));
    size_t size = sizes[0];

    std::vector<T> result;
    result.reserve(size);

    for (size_t i = 0; i < size; ++i)
    {
        result.emplace_back((argVec[i])...);
    }

    return result;
}

Does this make sense?

\$\endgroup\$
  • \$\begingroup\$ Couldn't Foo just be a struct? \$\endgroup\$ – Jamal May 24 '14 at 2:39
  • \$\begingroup\$ @Jamal This is a simplified the example. If I put all the stuff that makes me need a class then the essence becomes harder to see. \$\endgroup\$ – isarandi May 24 '14 at 12:56
3
\$\begingroup\$

I see one error:

assert(std::all_of(sizes.begin(), sizes.end(), [&](size_t s){return s=sizes[0];}));
                                                                     ^

This is an assignment, not a test. You probably meant s == sizes[0].
You can help this by passing s as a const value:

assert(std::all_of(sizes.begin(), sizes.end(), [&](size_t const s){return s == sizes[0];}));

Additionally, you may not mind destroying your old vectors (via move). So it may be worth looking at using move construction on the result vector:

std::vector<T> zipConstruct(std::vector<Arg>&... argVec)
{                                //        ^^^  pass by reference as you may modify them

      result.emplace_back(std::move(argVec[i])...);
                      //  ^^^^^^^^^^   Add standard move to get move semantics.
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.