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

时间:2016-01-15 18:41:39

标签: c++ c++11 stl containers default-constructor

使用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版本std::list::value_type,也应DefaultInsertable

我希望一元resize(std::size_t)仅用于“减小尺寸”目的,仅用于上述类型的容器。如果resize(std::size_t, value_type = value_type())不是DefaultConstructible,则可以禁止resize(std::size_t)参与重载决策(例如,使用基类调度)以支持resize(std::size_t, value_type) / value_type对。如果所需的大小更大,那么当前大小resize(std::size_t)应该抛出std::bad_alloc。有可能设计吗?

1 个答案:

答案 0 :(得分:3)

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

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

因此,如果您致电l.resize(size, dummy_value),您已取消对该类型的限制。此处dummy_value可能是l.front(),也可能是您方便使用的任何其他元素。如果size参数小于l.size(),则无论如何都不会使用它。