• C++11delete与default


    我们先讲众所周知的基本概念,再讲点别的

    弃置函数

    如果使用特殊语法 = delete ;取代函数体,那么该函数被定义为弃置的(deleted)。任何弃置函数的使用都是非良构的(程序无法编译)。这包含调用,包括显式(以函数调用运算符)及隐式(对弃置的重载运算符、特殊成员函数、分配函数等的调用),构成指向弃置函数的指针或成员指针,甚至是在不求值表达式中使用弃置函数。但是可以隐式 ODR 使用刚好被弃置的非纯虚成员函数。

    如果函数被重载,那么首先进行重载决议,且只有在选择了弃置函数时程序才非良构:

    struct sometype
    {
        void* operator new(std::size_t) = delete;
        void* operator new[](std::size_t) = delete;
    };
    sometype* p = new sometype; // 错误:尝试调用弃置的 sometype::operator new

    函数的弃置定义必须是翻译单元中的首条声明:已经声明过的函数不能声明为弃置的:

    struct sometype { sometype(); };
    sometype::sometype() = delete; // 错误:必须在首条声明弃置

    由用户提供的函数

    如果一个函数由用户声明且没有在它的首个声明被显式预置或显式弃置,那么它由用户提供。由用户提供的显式预置的函数(即在它的首个声明后被显式预置)在它被显式预置的地方定义;如果该函数被隐式定义为弃置的,那么程序非良构。需要为不断变化的代码库提供稳定的二进制接口的情况下,在函数的首个定义后再声明为预置可以保证执行效率,也能提供简明的定义。

    // trivial 的所有特殊成员函数都分别在它们的首个声明处被显式预置,
    // 因此它们都不由用户提供
    struct trivial
    {
        trivial() = default;
        trivial(const trivial&) = default;
        trivial(trivial&&) = default;
        trivial& operator=(const trivial&) = default;
        trivial& operator=(trivial&&) = default;
        ~trivial() = default;
    };
     
    struct nontrivial
    {
        nontrivial(); // 首个声明
    };
     
    // 没有在首个声明处被显式预置,
    // 因此该函数由用户提供并在此定义
    nontrivial::nontrivial() = default;

     文档说明:函数声明 - cppreference.com

    直接看代码

    1. #include
    2. struct Test {
    3. void a(double x) {}
    4. void a(int x) = delete;
    5. template<class T>
    6. void f(T c){}
    7. template<>
    8. void f(int c) = delete;
    9. };
    10. void a(double x) {}
    11. void a(int x) = delete;
    12. int main() {
    13. //Test().a(10);//error
    14. Test().a(10.0);
    15. //Test().f(10);//error
    16. Test().f(10.0);
    17. //a(10)//error
    18. a(10.0);
    19. }

    这种写法很有趣且简洁,要比C++20约束之类的去除单个类型更加直观,且还能作用于全局函数,成员函数重载的情况,与模板特例化的情况

    我可以说,这C++11的语法,几乎没有什么书会介绍这种写法,它非常好用且简洁

    我们分别举例的是成员函数,模板特例化,全局函数

  • 相关阅读:
    在springboot中如何开启Bean数据校验
    【Web前端】HTMLCSS一文详解
    回归预测 | MATLAB实现GRU(门控循环单元)多输入单输出
    【Python 实战】---- 使用【百度人像分割】实现一键批量抠图
    华为云HECS云服务器docker环境下安装redis
    C# 字符串string转换为double、float、int数据类型变量的方法
    【Lua】VSCode 搭建 Lua 开发环境
    TFT LCD刷新原理及LCD时序参数总结(LCD时序,写的挺好)
    算法刷题路线总结与相关资料分享
    JS遍历对象的七种方法
  • 原文地址:https://blog.csdn.net/a4364634611/article/details/126870746