为何右值引用模板变量b<int>能够绑定到左值a?
模板右值引用绑定左值的疑问解答
首先明确两个关键点:
- 代码中
decltype(b<int>)输出为int&&是完全正确的:因为显式指定模板参数T=int,所以变量b<int>的类型就是int&&,这就是程序输出same的原因。 - 但这段代码本身在标准C++中是无法编译通过的——你不能直接用左值
a初始化右值引用变量,编译器应该抛出类似“无法将左值绑定到右值引用”的错误。如果你的代码编译通过了,那是所用编译器做了非标准扩展。
核心原因辨析
你可能混淆了普通右值引用和转发引用:
- 当
T&&是显式指定模板参数的场景(比如这里的b<int>),它就是普通的右值引用,只能绑定到右值(比如临时对象、通过std::move转换后的左值),不能直接绑定左值。 - 只有当
T&&处于模板参数推导的场景(比如函数模板的参数template<typename T> void func(T&& arg)),它才是转发引用,此时可以根据传入的实参类型自动折叠为左值引用或右值引用,从而绑定左值或右值。
如果想要让这段代码符合标准,需要将初始化表达式改为std::move(a),通过强制转换把左值a转为右值引用,才能合法绑定到int&&类型的变量:
#include <iostream> #include <utility> // 引入std::move int a = 3; template<typename T> T&& b = std::move(a); int main() { if(std::is_same_v<decltype(b<int>), int&&>) { std::cout << "same\n"; } else { std::cout << "different\n"; } }
内容的提问来源于stack exchange,提问作者cpp
相关产品推荐
相关产品推荐

