关于用户提供的显式默认函数被隐式删除时程序非法的疑问
关于C++用户提供函数与显式删除函数的疑问解答
根据C++标准定义:用户声明且首次声明未显式默认或删除的函数为用户提供函数;用户提供的显式默认函数(即首次声明后显式默认的函数)在显式默认点定义,若被隐式定义为删除则程序非法。
比如下面的结构体中,所有特殊成员函数都采用了显式默认:
struct trivial { trivial() = default; trivial(const trivial&) = default; trivial(trivial&&) = default; trivial& operator=(const trivial&) = default; trivial& operator=(trivial&&) = default; ~trivial() = default; };
疑问点
我写出了下面这段显式删除所有特殊成员函数的代码,它能正常运行,这和上面的定义表述有冲突吗?
struct trivial { trivial() = delete; trivial(int){}; trivial(const trivial&) = delete; trivial(trivial&&) = delete; trivial& operator=(const trivial&) = delete; trivial& operator=(trivial&&) = delete; ~trivial() = delete; };
核心区别解释
那段定义只针对**显式默认(= default)**的函数,和显式删除的函数是完全不同的两种情况:
- 显式默认的函数,是你要求编译器帮你生成符合规则的默认实现。但如果因为类的某些特性(比如包含无法默认构造的成员),编译器没法生成有效实现,这个函数会被隐式删除,此时程序就会非法——毕竟你要求生成,但编译器做不到。
- 显式删除(
= delete)的函数,是你主动告诉编译器“这个函数不能被调用,也不需要存在实现”。编译器不会尝试生成它的代码,只要你在程序里没有调用这些被删除的函数(比如你的代码只用到了自定义的trivial(int)构造函数),程序就能正常编译运行。
简单说,显式删除是你主动禁用函数,显式默认是你请求编译器生成函数但可能失败——这就是为什么你的删除版代码能正常运行,和那段定义完全不冲突。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

