11-4 删除函数

在某些情况下,可能编写出在调用特定类型值时行为异常的函数。

请看以下示例:

#include <iostream>

void printInt(int x)
{
    std::cout << x << '\n';
}

int main()
{
    printInt(5);    // okay: prints 5
    printInt('a');  // prints 97 -- does this make sense?
    printInt(true); // print 1 -- does this make sense?

    return 0;
}

该示例输出:

image

虽然 printInt(5) 显然正常,但另外两次 printInt() 调用则值得商榷。对于 printInt(‘a’),编译器会判断可将 ‘a’ 提升为 int 值 97 以匹配函数调用与定义。同时将 true 提升为 int 值 1,且不会报错。

假设我们认为用 char 或 bool 类型调用 printInt() 毫无意义,该如何处理?


使用 = delete 限定符删除函数

当明确需要禁用函数调用时,可通过 = delete 限定符将该函数标记为已删除。若编译器发现函数调用指向已删除的函数,编译过程将因编译错误而终止。

以下是采用此语法的更新版本:

#include <iostream>

void printInt(int x)
{
    std::cout << x << '\n';
}

void printInt(char) = delete; // calls to this function will halt compilation
void printInt(bool) = delete; // calls to this function will halt compilation

int main()
{
    printInt(97);   // okay

    printInt('a');  // compile error: function deleted
    printInt(true); // compile error: function deleted

    printInt(5.0);  // compile error: ambiguous match

    return 0;
}

image

我们快速分析几个示例:首先,printInt(‘a’) 与被删除的 printInt(char) 直接匹配,因此编译器报错。printInt(true) 与被删除的 printInt(bool) 直接匹配,同样导致编译错误。

printInt(5.0) 是个有趣的案例,结果可能出乎意料。编译器首先检查是否存在精确匹配的 printInt(double),未找到。接着尝试寻找最佳匹配。尽管 printInt(int) 是唯一未被删除的函数,但在函数重载解析中仍会考虑已删除函数作为候选项。由于所有函数均无法明确确定最佳匹配,编译器将报出模糊匹配编译错误。

关键要点
= delete 表示“我禁止此项”,而非“此项不存在”。
删除函数参与函数重载解析的所有阶段(不仅限于精确匹配阶段)。若被选中的函数已被删除,则导致编译错误。

对于进阶读者
其他类型的函数也可采用类似方式删除。
第14.14节——复制构造函数介绍将讨论删除成员函数,第11.7节——函数模板实例化 将探讨删除函数模板特化。


删除所有不匹配的重载函数(进阶)

逐个删除函数重载虽可行,但可能冗长。有时我们希望特定函数仅接受与实参类型完全匹配的形参。可通过函数模板(详见后续第11.6节——函数模板)实现如下:

#include <iostream>

// This function will take precedence for arguments of type int
void printInt(int x)
{
    std::cout << x << '\n';
}

// This function template will take precedence for arguments of other types
// Since this function template is deleted, calls to it will halt compilation
template <typename T>
void printInt(T x) = delete;

int main()
{
    printInt(97);   // okay
    printInt('a');  // compile error
    printInt(true); // compile error

    return 0;
}

image

posted @ 2026-03-06 16:44  游翔  阅读(0)  评论(0)    收藏  举报