关于std::add_lvalue_reference/add_rvalue_reference与cv限定类型的技术问询
关于std::add_lvalue_reference/std::add_rvalue_reference与cv-qualified类型的疑问
嘿,我来帮你理清这个容易混淆的点!首先直接给你结论:带const/volatile限定的对象或函数类型,完全可以被std::add_lvalue_reference和std::add_rvalue_reference转换成对应的引用类型——你误解了cppreference描述里“无cv或引用限定符”的意思。
咱们拆解一下这段描述的准确含义:
cppreference里的这句话,核心是在区分两种情况:T是不是引用类型,以及T是不是对象/函数类型。这里的表述有点简化,容易让人误解:
- “无引用限定符”很好理解:指T本身不是左值引用(
U&)也不是右值引用(U&&); - 而“无cv限定符”并不是说要排除带const/volatile的类型,而是指“T是一个对象类型或函数类型(无论是否带有cv限定)”——换句话说,只要T是对象/函数类型(哪怕是
const int、volatile void()这种带cv的),并且不是引用类型,那么add_rvalue_reference会生成T&&,add_lvalue_reference会生成T&。
举几个实际例子,一看就明白:
- 对于
const int(带cv的对象类型,非引用):std::add_lvalue_reference<const int>::type→const int&(左值引用到const int)std::add_rvalue_reference<const int>::type→const int&&(右值引用到const int)
- 对于
const int&(已经是左值引用类型):std::add_lvalue_reference<const int&>::type→const int&(引用折叠规则:左值引用的左值引用还是左值引用)std::add_rvalue_reference<const int&>::type→const int&(引用折叠规则:左值引用的右值引用还是左值引用)
- 对于
void(非对象/函数类型):- 不管是add_lvalue还是add_rvalue,结果都是
void——因为void类型不能被引用。
- 不管是add_lvalue还是add_rvalue,结果都是
那cppreference为什么要提到“无cv或引用限定符”?其实是为了排除那些已经是引用的类型,以及非对象/函数的类型。只有当T是一个“纯”的对象/函数类型(没有被引用修饰,不管有没有cv),才会生成新的引用类型;如果T已经是引用,或者是void这类不能引用的类型,就直接返回T本身。
最后再给你总结一下核心规则,方便记忆:
std::add_lvalue_reference
- 若T是对象/函数类型(含cv限定),或是右值引用
U&&:结果是T&(引用折叠后变成U&) - 若T是左值引用
U&:结果就是U& - 其他类型(如void):结果就是T本身
std::add_rvalue_reference
- 若T是对象/函数类型(含cv限定),或是左值引用
U&:结果是T&&(引用折叠后变成U&) - 若T是右值引用
U&&:结果就是U&& - 其他类型(如void):结果就是T本身
内容的提问来源于stack exchange,提问作者anton_rh
相关产品推荐
相关产品推荐

