求C++中引用合并(reference coalescence)的标准规范术语
关于C++引用合并的规范术语及相关场景解析
你提到的“引用合并”在C标准里的正式术语是引用折叠(reference collapsing),这是C11引入右值引用后确立的核心规则之一,专门用来描述不同引用类型组合后最终的类型解析逻辑。
一、引用折叠的核心规则
引用折叠只发生在特定上下文(比如模板参数推导、auto类型推导、typedef/using别名展开等)中,规则非常清晰:
- 左值引用和任何引用组合都会折叠成左值引用:
T& &→T&,T&& &→T&,T& &&→T& - 两个右值引用组合才会折叠成右值引用:
T&& &&→T&&
二、你提到的模板与函数指针场景解析
你说的“在模板上下文及函数指针场景下‘合并’引用,例如void (*)()等价于void()”,其实是引用折叠结合函数类型隐式转换的综合表现:
- 模板上下文:当模板参数推导涉及函数类型时,函数类型的引用会触发折叠。比如:
template<typename T> void deduce(T&& arg) {} void foo() {} int main() { // foo是左值函数,T会被推导为void(&)(),然后T&&折叠为void(&)() deduce(foo); // 传递函数指针时 void(*fp)() = foo; deduce(fp); // T推导为void(*)(),T&&是void(*&&)(),折叠为void(*&)() } - 函数指针场景:你感觉
void (*)()和void()“等价”,本质是C++中函数类型可以隐式转换为指向该函数的指针(函数到指针的退化)。如果结合引用折叠的场景,比如在模板中处理函数类型的引用时,会出现类似“合并”的效果,让两种类型的表现看起来更统一。
再举个auto推导的直观例子:
void bar() {} auto& ref = bar; // ref的类型是void(&)() auto&& ref2 = bar; // 因为bar是左值,ref2的类型是void(&)()(触发引用折叠)
总结一下:你要找的规范术语就是引用折叠(reference collapsing),它涵盖了你提到的模板上下文里的引用合并逻辑;而函数指针场景的表现,是引用折叠加上函数到指针的隐式退化共同作用的结果。
内容的提问来源于stack exchange,提问作者v.oddou
相关产品推荐
相关产品推荐

