为何下述代码无法编译?替换int&为int则编译正常的原因
问题解答
编译失败原因
当你将模板参数指定为int&时,引用折叠会导致两个add成员函数的签名完全一致,触发编译器的重载冲突错误:
error: ‘void my_collection::add(T&&) [with T = int&]’ cannot be overloaded with ‘void my_collection::add(T&) [with T = int&]’
对应代码
#include <iostream> using namespace std; template <typename T> struct my_collection { void add(T& thing) { } void add(T&& thing) { cout << is_lvalue_reference<T>::value << endl; } }; int main(){ my_collection<int&> a; return 0; }
详细分析
模板参数为
int&的情况
C++的引用折叠规则是:T& &、T& &&、T&& &都会折叠为T&- 只有
T&& &&会折叠为T&&
当实例化
my_collection<int&>时:- 第一个
add函数的参数T&展开为int& &,折叠后是int& - 第二个
add函数的参数T&&展开为int& &&,折叠后也是int&
两个函数的签名完全相同,不符合C++的重载要求,因此编译报错。
模板参数为
int的情况
此时:- 第一个
add函数的参数是int&(左值引用) - 第二个
add函数的参数是int&&(右值引用)
两个函数的签名不同,满足重载规则,所以编译成功。
- 第一个
内容的提问来源于stack exchange,提问作者G.yang
相关产品推荐
相关产品推荐

