使用一元调整大小减小非默认可构造元素的容器大小

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

使用push_back/emplace_back(罕见push_front/emplace_front甚至push_after/emplace_after)我几乎可以装满任何容器来自STL。甚至是非默认可构造元素的容器。减小尺寸只需要存在元素的析构函数(此外,容器必然要求元素为 Destructible)。但我不能简单地使用 resize (如果存在)来减小非默认可构造元素的容器的大小。相反,我必须使用一种解决方法,即使是对它们的最不严格(对特殊功能):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;
}

即使是一元 std::list::resize version std::list::value_type should be DefaultInsertable

我希望一元 resize(std::size_t) 仅在上述类型的容器中用于 "decrease size" 目的。如果 value_type 不是 DefaultConstructible。如果所需大小大于当前大小,例如 resize(std::size_t) 应该抛出 std::bad_alloc。是否可以设计?

value_type 必须是默认可构造的 (DefaultInsertable),因为 resize 的接口包含增加和减少大小的代码。即使你只用了一半的代码,整个函数也得编译。

还有一个 two-parameter resize,您可以在其中提供增加大小时要使用的值。在这种情况下,value_type 不必是默认可构造的。

因此,如果您调用 l.resize(size, dummy_value),您就解除了对类型的限制。这里 dummy_value 可能是 l.front(),或者您手边的任何其他元素。如果size参数小于l.size(),无论如何都不会使用