You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中模板函数=delete与explicit修饰成员函数的区别是什么

两种写法的核心差异与原理说明

1. 第二种写法本身属于非法C++语法

explicit关键字的适用场景只有两类:

  • 修饰类的构造函数,避免该构造函数被用于隐式类型转换
  • 修饰用户自定义的类型转换函数,避免该转换被隐式调用

它不能用于修饰普通成员函数,你写的explicit void f(double d);会直接被编译器报语法错误,完全无法达到你想要的「禁止参数隐式转换」的效果。

2. 模板=delete写法的工作逻辑

第一种写法是C++11及以后标准下,实现「仅接受某一特定类型参数、禁止所有隐式转换」的标准实现,原理如下:

  • 当传入参数的类型严格为double时,重载决议会优先匹配非模板的void f(double d),函数正常调用
  • 当传入其他任意类型的参数时(哪怕该类型可以隐式转换为double,比如int、float、long等),模板函数template<class T> void f(T)会实例化出对应类型的重载,重载决议的优先级高于需要做隐式类型转换的非模板函数,而该模板函数被标记为=delete,编译器会直接抛出调用已删除函数的错误,刚好实现了禁止隐式转换的需求。

举个实际调用的例子:

OnlyDouble od;
od.f(1.0); // 正常调用,参数为double
od.f(1); // 编译报错,匹配到删除的f<int>(int)
od.f(1.0f); // 编译报错,匹配到删除的f<float>(float)

3. 补充说明

如果你使用的是C++20及以上标准,也可以用concept实现等价效果,写法更简洁:

struct OnlyDouble
{
    void f(std::same_as<double> auto d);
};

效果和第一种模板=delete的写法完全一致。

内容的提问来源于stack exchange,提问作者heretoinfinity

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 04:09:01