有效的现代C++第146页:

void processWidget(std::shared_ptr<Widget> spw, int priority);
void cusDel(Widget *ptr);//a custom deleter
在C++ 17之前,这是不安全的调用:
processWidget(std::shared_ptr<Wdiget>(new Widget, cusDel), computePriority());
它曾经是不安全的,因为可以在new Widget之后但在std::share_ptr构造函数之前调用computePriority,并且如果computePriority产生异常,则动态分配的Widget将被泄漏。
因此,您可以这样做:
std::shared_ptr<Widget> spw(new Widget, cusDel);
processWidget(spw, computePriority());
现在,这将在shared_ptr上添加一个复制构造函数操作。因此,您也可以这样做:
std::shared_ptr<Widget> spw(new Widget, cusDel);
processWidget(std::move(spw), computePriority());
所以我的问题是,下面的代码是否仍然能够泄漏C++ 17中的内存?
processWidget(std::shared_ptr<Wdiget>(new Widget, cusDel), computePriority());
我已经阅读了thisthis,但仍然不确定,我相信std::shared_ptr<Wdiget>(new Widget, cusDel)computePriority()都在调用processWidget之前进行了排序,但是我认为computePriority()仍然可以在new之后和shared_ptr取得新创建对象的所有权之前引发异常。 。

最佳答案

C++ 17确实改变了关于用于调用函数的表达式的求值的顺序。尽管它没有强加任何特定的顺序,但it does say:

“不确定地排序” is defined as:

因此,一个参数将在其他参数之前进行初始化,包括所有副作用。因此,第一个参数或第二个参数首先要经过充分评估。

10-05 23:44