Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Looped push_back against resize() + iterator

Tags:

c++

stl

Simple question; what's better and why?



    out.resize( in.size() );
    T1::iterator outit = out.begin();
    for( inIt = in.begin() to end, ++inIt, ++outIt )
       *outit = *inIt
OR

    out.erase();
    for( inIt = in.begin() to end, ++inIt )
        out.push_back( inIt );


I'm assuming the memory assignment implicit in push_back is worth avoiding but want to make sure.

Thanks

EDIT: Thanks for the out = in suggestions guys ;). The actual code I'm playing with is:


template//can't stop the browser ignoring th class T1, class T2 in angle brackets
bool asciihex( T1& out, const T2& in )
{
    //out.erase();
    out.resize( in.size() / 2 );
    if( std::distance( in.begin(), in.end() ) % 2 )//use distance rather than size to minimise the requirements on T2?
        return false;
    for( T2::const_iterator it = in.begin(); it != in.end(); it += 2 )
    {
        out.push_back(((( (*it > '9' ? *it - 0x07 : *it)  - 0x30)  '9' ? *(it+1) - 0x07 : *(it+1)) - 0x30) & 0x000f));
    }
    return true;
}

template
bool asciihex( T1& out, const T2& in )
{
    size_t size = in.size();
    if( size % 2 )//use distance rather than size to minimise the requirements on T2?
        return false;
    out.resize( size / 2 );
    T1::iterator outit = out.begin();
    for( T2::const_iterator it = in.begin(); it != in.end(); it += 2, ++outit )
    {
        *outit = ((( (*it > '9' ? *it - 0x07 : *it)  - 0x30)  '9' ? *(it+1) - 0x07 : *(it+1)) - 0x30) & 0x000f);
    }
    return true;
}

Edit: I've marked push_back as the answer as it seems to be the consensus and, therefore, more useful to anyone else with the same problem. However I have ended up using the iterator method as one of the container classes I'm interested in doesn't support push_back... mileage varies.


2 Answers

The second, and if you're concerned about multiple extensions use out.reserve(). The right answer to adding to a vector is almost always push_back or back_inserter, which avoid some possible problems (exception guarantees, constructors, writing past the end, for example) that you'd have to pay attention to with other methods.

like image 57
David Thornley Avatar answered Feb 08 '26 00:02

David Thornley


The second one, as long as you reserve the right capacity first.

One problem I see (apart from style) is that in the first one, if your copy assignment throws, you have taken an operation that should give you the strong guarantee, and used it to give no guarantee.

like image 32
Greg Rogers Avatar answered Feb 07 '26 23:02

Greg Rogers



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!