C++中右值引用模板与字面量实参的模板实参推导疑问
关于C++模板实参推导中转发引用的推导问题
我正在学习C++的模板实参推导,cppreference中对**P(模板参数类型)和A(推导所得类型)**的定义是:模板实参推导尝试确定模板实参(类型模板参数的类型、模板模板参数的模板、非类型模板参数的值),将其代入每个参数P以生成推导所得类型A。
其中关于转发引用的规则是:若P是指向无cv限定模板参数的右值引用(即转发引用),对应函数调用实参是左值时,推导会用A的左值引用替代A(这是std::forward的实现基础,C++17起类模板实参推导中无转发引用)。对应的示例代码如下:
template<class T> int f(T&&); // P是指向无cv限定T的右值引用(转发引用) template<class T> int g(const T&&); // P是指向带cv限定T的右值引用(无特殊处理) int main() { int i; int n1 = f(i); // 实参是左值:调用f<int&>(int&)(特殊情况) int n2 = f(0); // 实参非左值:调用f<int>(int&&) // int n3 = g(i); // 错误:推导为g<int>(const int&&),无法将右值引用绑定到左值 }
针对调用int n2 = f(0)的场景,P为T&&,0是int类型的右值(即A为int),如何推导出模板参数T为int?
解答
当实参是右值时,转发引用的左值特殊处理规则不生效,直接按常规逻辑推导:
我们需要找到模板参数T,使得代入后的T&&能匹配实参的类型int(右值)。因为0不是左值,不需要将A转为左值引用,推导时直接去掉P的引用修饰符即可——T&&去掉&&后得到T,而A是int,因此T的类型就是int。代入后P变为int&&,正好可以绑定到int类型的右值0,完全符合匹配规则。
内容的提问来源于stack exchange,提问作者吴yuer
相关产品推荐
相关产品推荐

