C++缩写函数模板无法按预期使用默认实参的原因是什么
问题原因
你观察到的现象是C++模板实参推导的标准规则导致的,和缩写函数模板的底层实现逻辑直接相关:
- C++20引入的缩写函数模板(参数用
auto声明的函数)本质等价于隐式声明的普通函数模板,你给出的代码:
#include <iostream> auto f(const auto x = 0) { return x + sizeof(x); } int main() { std::cout << f() << std::endl; // << broken std::cout << f(0) << std::endl; std::cout << f(short(8470)) << std::endl; }
中f的实际等效写法为:
template <typename T> auto f(const T x = 0) { return x + sizeof(x); }
- 按照C++标准的模板实参推导规则,调用函数模板时如果没有显式指定模板实参,推导过程不会参考函数的默认实参,只会根据调用时传入的实参类型推导模板参数类型。调用
f()时没有传入任何实参,编译器无法推导出模板参数T的类型,因此编译报错。 - 你猜测的"模板推导机制不会读取默认实参的取值"完全符合标准规则。默认实参只有在模板参数已经确定(要么被推导出来,要么被显式指定)之后才会被使用,它本身不参与模板参数的推导过程。
解决方案
如果需要支持无参调用,有两种常用实现方式:
- 调用时显式指定模板参数类型,比如
f<int>(),此时模板参数T已经确定为int,默认实参0就会正常生效 - 不使用缩写函数模板,手动写完整的函数模板并给模板参数设置默认类型:
template <typename T = int> auto f(const T x = 0) { return x + sizeof(x); }
这种写法下调用f()就可以正常编译运行,模板参数T会优先使用默认的int类型。
内容的提问来源于stack exchange,提问作者NoSenseEtAl
相关产品推荐
相关产品推荐

