jac*_*k X 6 c++ templates language-lawyer
推导转换函数模板的模板参数的规则位于temp.deduct.conv部分。
第一条规则指定对应的P和A是什么,第一个问题在这里:
模板参数推导是通过将转换函数模板的返回类型(称为 P)与正在查找的转换函数 id 的转换类型 id 指定的类型(称为 A)进行比较来完成的,如 [温度扣除类型]。如果 conversion-function-id 是在重载决策 ([over.match.funcs]) 期间构造的,则应用以下转换。
#include <iostream>
struct C{
template<typename Type>
operator Type(){
Type a{};
/*a = 1;*/
return a;
}
};
int main(){
int const& rf = C{};
}
Run Code Online (Sandbox Code Playgroud)
对于这个例子,P 应该是,Type但是 A 是什么?似乎只有一条规则与之相关:
over#match.funcs.general-7
在考虑类 S 的转换函数来初始化类型 T 的对象或引用的每种情况下,候选函数包括在 S 中搜索转换函数 ID 运算符 T的结果。
我不知道 A 是否仅存在int const&于此,或者是否是为此初始化定义的任何允许的类型。
如果 A 由前者决定,则 P 为Type且 A 为int const&。
根据第 2 条:
如果 P 是引用类型,则使用 P 引用的类型代替 P 进行类型推导以及本子条款其余部分中对 P 的任何进一步引用或转换。
因此,变换后的 P 仍然是Type,那么这样的 P/A 对将经历项目符号 3
如果 A 不是引用类型:
- [...]
因为 A 是引用类型,所以跳过第 3 点。继续第 4 点
如果 A 是 cv 限定类型,则类型推导将忽略 A 类型的顶级 cv 限定符。如果A是引用类型,则使用A引用的类型进行类型推导。
经过第 4 条,现在 A 转变为int const。
第 5 条说:
一般来说,推导过程尝试找到模板参数值,使推导的 A与 A相同。但是,A 的某些属性可能会被忽略:
- 如果原始 A 是引用类型,则 A 的任何 cv 限定符(即引用引用的类型)。
- 如果原始 A 是函数指针或成员函数指针类型,则其为 noexcept。
- A 中可以通过限定转换恢复的任何 cv 限定符。
仅当类型推导失败时才会忽略这些属性。
这里有一个问题,编译器说推导的 A 是int,但是 IIUC 推导Type自const int,推导的类型不是const int吗?为什么推导的模板参数是int而不是const int?
如果将转换函数模板更改为
#include <iostream>
struct C{
template<typename Type>
operator Type&(){
static Type a{};
a = 1;
return a;
}
};
int main(){
int const& rf = C{};
}
Run Code Online (Sandbox Code Playgroud)
则将Type推导为const int. 为什么此时推导出来的类型与上面的例子不一样呢?(它们应该是相同的结果,即const int)。Type在第一个示例中,我错过了从“const int”推导的任何内容吗?
| 归档时间: |
|
| 查看次数: |
198 次 |
| 最近记录: |