简体   繁体   中英

Decrease size of container of non-default-constructible elements using unary resize

Using push_back / emplace_back (rare push_front / emplace_front or even push_after / emplace_after ) I can fill almost any container from the STL. Even container of non-default-constructible elements. Size decreasing requires only a presence of elements' destructors (moreover, containers necessarily require, that the elements to be Destructible ). But I can't simply use resize (if present) to reduce size of containers of non-default-constructible elements. Instead I have to use a workaround even for a least exacting (to special functions) of them: std::list .

#include <list>

#include <cstdlib>

int
main()
{
    // construct
    std::list< std::reference_wrapper< int > > l;
    // fill
    int i{};
    l.emplace_back(i);
    int j{};
    l.emplace_back(j);
    // save intermediate state for future
    std::size_t const size = l.size();
    // continue appending
    int k{};
    l.emplace_back(k);
    // now I want to rollback to saved state
    //l.resize(size); // just need to call the destructors, but illegal due to not default constructible value_type
    // so I have to use a workaround
    for (std::size_t s = l.size(); size < s; --s) {
        l.pop_back();
    }
    return EXIT_SUCCESS;
}

Even for unary std::list::resize version std::list::value_type should be DefaultInsertable .

I want unary resize(std::size_t) be intended for "decrease size" purpose only in described above kind of containers. It is possible to prohibit resize(std::size_t, value_type = value_type()) participation in overloading resolution (say, using base class dispatching) in favor of resize(std::size_t) / resize(std::size_t, value_type) pair if value_type is not DefaultConstructible . If desired size is greater then current size such resize(std::size_t) should throw, say, std::bad_alloc . Is it possible design?

The value_type has to be default constructible (DefaultInsertable) because the interface to resize contains code to both increase and decrease the size. Even if you just use half the code, the entire function has to compile.

There is also a two-parameter resize where you supply the value to use when the size is increased. In that case, the value_type doesn't have to be default constructible.

So, if you call l.resize(size, dummy_value) you have lifted the restriction on the type. Here dummy_value might be l.front() , or any other element you have handy. If the size parameter is less than l.size() , it will not be used anyway.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM