当前位置: 首页 > 知识库问答 >
问题:

C语言中的预期析构函数

齐夕
2023-03-14

我有这个代码,输出如下:

链接到下面的示例https://godbolt.org/z/z8Pn9GsTv

template <typename T>
struct A1 {
    A1() {
        std::cout << "construction of a1" << std::endl;
    }

    ~A1() {
        std::cout << "destruction of a1" << std::endl;
    }
    ~A1() requires (std::is_same_v<T,int>) {
        std::cout << "it is an int" << std::endl;
    }
};

int main() {
    A1 <int>a;
    
    return 0;
}

输出:

construction of a1
destruction of a1

但交换析构函数的位置会产生其他结果:

代码链接https://godbolt.org/z/vxj7dPqaj

template <typename T>
struct A1 {
    A1() {
        std::cout << "construction of a1" << std::endl;
    }

    ~A1() requires (std::is_same_v<T,int>) {
        std::cout << "it is an int" << std::endl;
    }
    ~A1() {
        std::cout << "destruction of a1" << std::endl;
    }
};

输出:

construction of a1
it is an int

想知道这是一个错误吗?

共有3个答案

隆飞驰
2023-03-14

在您的类模板上,您有两个析构函数定义配方。在实例化期间,编译器获取与所需签名匹配的“第一”配方。取决于编译器,取决于结果。我认为clang、gcc和Ming w将提供相同的结果,msvc方法不同。https://cplusplus.github.io/CWG/issues/1495.html

红朝
2023-03-14

在你的第二个密码里,

尝试改变这一点:

A1 <int>a;

对此:

A1 <double>a;

您将获得输出:

construction of a1
destruction of a1 // With MSVC & GCC compiler

我在这里的解释是,当第一个构造函数的条件(要求)失败时,调用2'nd构造函数,它打印“销毁a1”并销毁a

这里有一个更详细的解释。。。

长孙沈义
2023-03-14

正如Quimby所指出的,这确实是一个报告的Clang bug1

请注意,第二个代码段(第一个带有约束析构函数的代码段)在Clang中并没有真正“起作用”,它只是忽略了第二个析构函数2

还要注意的是,与gcc不同,在我写这篇文章的时候,Clang似乎还没有实现[P0848R3](这是关于条件平凡的特殊成员函数)但是3

1)https://bugs.llvm.org/show_bug.cgi?id=50570
2)参见例如:https://godbolt.org/z/rff7qfK65
3)查看功能测试宏__cpp_concepts的报告值,例如此处:https://godbolt.org/z/P4z3Pj5vT

 类似资料:
  • 1. 函数的定义 程序是由一个个函数组成的。我们之前虽然没有正式介绍函数,但是我们早已经开始使用函数了。因为离开了函数,我们的程序没有办法正常的工作。只不过我们使用的是 C 语言内置的标准函数库。 那么函数是什么? 函数是由一组语句组成完成至少一个特定任务的语句的集合。在 C 语言中,我们必须要包含一个函数,就是我们最开始介绍的 mian 函数。 2. 为什么需要函数? 函数帮助我们可以减少代码的

  • 在 Go 语言开篇中我们已经知道,Go 语言与 C 语言之间有着千丝万缕的关系,甚至被称之为 21 世纪的C语言。 所以在 Go 与 C 语言互操作方面,Go 更是提供了强大的支持。尤其是在 Go 中使用 C,你甚至可以直接在 Go 源文件中编写 C 代码,这是其他语言所无法望其项背的。 格式: 在 import "C" 之前通过单行注释或者通过多行注释编写C语言代码 在 import "C" 之

  • 本文向大家介绍浅析C语言中strtol()函数与strtoul()函数的用法,包括了浅析C语言中strtol()函数与strtoul()函数的用法的使用技巧和注意事项,需要的朋友参考一下 C语言strtol()函数:将字符串转换成long(长整型数) 头文件: strtol() 函数用来将字符串转换为长整型数(long),其原型为: 【参数说明】str 为要转换的字符串,endstr 为第一个不能

  • 与《 构造函数》类似,C# 中的析构函数(也被称作“终结器”)同样是类中的一个特殊成员函数,主要用于在垃圾回收器回收类实例时执行一些必要的清理操作。 C# 中的析构函数具有以下特点: 析构函数只能在类中定义,不能用于结构体; 一个类中只能定义一个析构函数; 析构函数不能继承或重载; 析构函数没有返回值; 析构函数是自动调用的,不能手动调用; 析构函数不能使用访问权限修饰符修饰,也不能包含参数。 析

  • 主要内容:析构函数的执行时机创建对象时系统会自动调用构造函数进行初始化工作,同样,销毁对象时系统也会自动调用一个函数来进行清理工作,例如释放分配的内存、关闭打开的文件等,这个函数就是析构函数。 析构函数(Destructor)也是一种特殊的成员函数,没有返回值,不需要程序员显式调用(程序员也没法显式调用),而是在销毁对象时自动执行。构造函数的名字和类名相同,而析构函数的名字是在类名前面加一个 符号。 注意:析构函数没有参数,

  • 本文向大家介绍C 语言程序结构示例解析,包括了C 语言程序结构示例解析的使用技巧和注意事项,需要的朋友参考一下 C 程序结构 在我们学习 C 语言的基本构建块之前,让我们先来看看一个最小的 C 程序结构,在接下来的章节中可以以此作为参考。 C Hello World 实例 C 程序主要包括以下部分: 预处理器指令 函数 变量 语句 & 表达式 注释 让我们看一段简单的代码,可以输出单词 "Hell