函数模板调用:空大括号初始化列表与类型推导问题
问题解析:模板参数推导与空初始化列表的特殊处理
先看原代码示例:
#include <optional> template <class T = int> void f(std::optional<T>); int main() { f(1); // (1) 编译失败 f({}); // (2) 编译成功 }
调用(1)编译失败的原因
模板类型推导的核心规则是:不会考虑实参到形参的隐式转换,只会直接匹配实参类型与形参的模板结构。
- 调用
f(1)时,实参类型是int,形参是std::optional<T>。 int和std::optional<T>属于完全不同的类型结构,编译器无法从int推导出模板参数T(没有任何线索指向需要将int转换为std::optional<int>),因此推导失败,编译报错。
调用(2)编译成功的原因
当实参是空初始化列表{}时,C++标准对模板推导有特殊规定:
- 空初始化列表无法提供任何用于推导模板参数
T的类型信息,编译器会放弃对T的推导,转而使用模板声明中指定的默认模板参数int。 - 此时函数模板被实例化为
void f(std::optional<int>),而std::optional<int>有默认构造函数,空初始化列表可以合法构造出std::optional<int>的默认实例,因此调用成功。
内容的提问来源于stack exchange,提问作者Igor R.
相关产品推荐
相关产品推荐

