在下列C++程式码中,函式fun1
的参数和函式ret1
的传回型别中的样板预留位置不会编译:
template <typename T = int>
class type {
T data;
};
void fun1(type arg); // Error: template placeholder not permitted in this context
void fun2(type<> arg); // Ok
void fun3(type<int> arg); // Ok
type ret1(); // Error: Deduced class type 'type' in function return type
type<> ret2(); // Ok
type<int> ret3(); // Ok
int main() {
type var1; // Ok!!!!!!
type<> var2; // Ok
type<int> var3; // Ok
}
但是,var1
是可以的。
- 为什么
var1
可以编译,而fun1
和ret1
不能? - 函数声明和变量声明之间的这种不一致行为背后是否存在逻辑?
2条答案
按热度按时间hgb9j2n61#
var1
得益于CTAD,其中所有非默认模板参数(即none)都可以从初始化中推导出来。然而,这两个函数声明都不是CTAD的候选对象,因此必须提供模板参数列表,即使该列表为空。课模板扣款
隐式生成的推演向导
在函数样式转换或 * 变量声明 * 中,当类型说明符仅由主类模板C的名称组成时(即,没有伴随的模板参数列表),演绎的候选项如下形成:
...
(着重号为后加)
8ljdwjyq2#
type var1;
正在使用类模板参数推导(CTAD),这在C17开始是可能的,并且从变量的初始化器推导模板参数(这里是空参数列表)。这在函数声明中是不可能的,因为没有初始值设定项可以从中推导出模板参数。
特别是对于一个函数参数,没有任何可能的来源来确定模板参数(除非这样的函数被认为是类似于C20缩写函数模板的模板)。
对于返回类型,可以像
auto
占位符返回类型那样指定它,但这并不是CTAD介绍的一部分。