首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >要求返回的类型,可能有一些成员的功能,SFINAE在功能的翻译单位?

要求返回的类型,可能有一些成员的功能,SFINAE在功能的翻译单位?
EN

Stack Overflow用户
提问于 2022-04-07 18:09:26
回答 1查看 61关注 0票数 1

为什么析构函数被隐式调用?精制

我对调用约定的理解是,函数在调用者要求它们的结果(或者在传统的地方?)构造它们的结果。考虑到这一点,这让我感到惊讶:

代码语言:javascript
复制
#include <memory>

struct X; // Incomplete type.

// Placement-new a null unique_ptr in-place:
void constructAt(std::unique_ptr<X>* ptr) { new (&ptr) std::unique_ptr<X>{nullptr}; }

// Return a null unique_ptr:
std::unique_ptr<X> foo() { return std::unique_ptr<X>{nullptr}; }

https://godbolt.org/z/rqb1fKq3x,而constructAt编译,愉快地放置-new的空unique_ptr<X>foo()不编译,因为编译器想要实例化unique_ptr<X>::~unique_ptr()。我理解它为什么不能实例化这个析构函数(因为就语言而言,它需要跟随d‘’tor的非nullptr分支,然后删除内存nullptr)。基本上,如果没有一个完整的Xunique_ptr的析构函数就会消失(对吧?)。但是为什么返回值的函数必须知道如何销毁该值呢?调用者不是必须销毁它的函数吗?

显然,我的constructAtfoo函数在道义上并不等同。这种语言是迂腐的,还是有一些代码路径(例外?)foo()必须在哪里销毁这个值?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-07 18:36:56

在特定情况下,不可能调用析构函数。但是,该标准指定了可能以更一般的方式调用析构函数的情况。如果一个析构函数可能被调用,它需要一个定义(即使没有可以调用它的路径),因此这将导致隐式实例化,这在您的情况下是失败的,因为std::unique_ptr<X>析构函数的实例化要求X是完整的。

特别是,对于return语句中的每个结果对象,都可能调用析构函数。

我认为CWG第2176期描述了这种选择的原因:通常,在构造return语句的结果对象之后,函数中可能有局部变量和临时变量被破坏。但是,如果销毁其中一个对象会抛出异常,那么已经构造的结果对象也应该被销毁。这需要定义析构函数。

然后,CWG第2426期使析构函数可能被调用,即使由于上述推理没有实际调用,这与实现是一致的。我认为做出这一选择只是因为它不需要编译器做出任何额外的决策,而且已经实现了。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71787027

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档