是否有关于std :: stack元素销毁顺序的保证?
我有一堂课,负责管理一组服务的生命周期。由于可能存在服务相互依赖关系,因此构建和销毁的顺序很重要-应该以与创建服务相反的顺序销毁服务。
我以为我会std::stack<std::unique_ptr<Service>>为此目的使用。我搜索了堆栈,并知道它可能会影响其销毁语义,因此我搜索了一下,但是找不到任何文档(第800页)来保证std :: stack元素的销毁顺序。
最后,我写了一个小测试:
struct Squealer {
Squealer() {
static int instance_count = 0;
this->instance = ++instance_count;
}
~Squealer() {
std::cout << "Destroying instance " << instance << std::endl;
}
int instance;
};
int main(int argc, char *[] argv) {
{
std::stack<Squealer> squealers;
squealers.emplace();
squealers.emplace();
squealers.emplace();
}
std::cout << "...done" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
结果符合预期:
Destroying instance 3
Destroying instance 2
Destroying instance 1
...done
Run Code Online (Sandbox Code Playgroud)
我应该依靠这种行为吗?是为std :: stack保证了天真的销毁顺序,还是我应该采取(显然很容易的)弹出步骤直到明确为止?
std::stack不是容器,而是容器适配器。它以您实际要使用哪个容器存储元素作为第二个参数:
template<
class T,
class Container = std::deque<T>
> class stack;
Run Code Online (Sandbox Code Playgroud)
的销毁语义stack<T>将是的deque<T>。但是,这对您并没有太大帮助,因为deque<T>标准的未指定销毁顺序。实际上,没有为任何序列容器指定它。
如果销毁顺序很重要,那么您应该执行以下两项操作之一:提供一个新容器,该容器首先销毁其元素:
template <class T>
struct my_deque : std::deque<T>
{
using std::deque<T>::deque;
~my_deque() {
while (!this->empty()) this->pop_back();
}
};
template <class T>
using my_stack = std::stack<T, my_deque<T>>;
Run Code Online (Sandbox Code Playgroud)
或提供自己stack的析构函数弹出所有元素的实现:
template <class T, class Container = std::deque<T>>
struct ordered_stack : std::stack<T, Container>
{
using std::stack<T, Container>::stack;
~ordered_stack() {
while (!this->empty()) {
this->pop();
}
}
};
Run Code Online (Sandbox Code Playgroud)