为何带模板与不带模板的重载函数调用结果不同?
为什么左值引用调用非模板和模板重载函数的结果不同?
先看代码运行的实际输出:
test: 2 test2: 1
下面分别拆解两组函数的匹配逻辑:
一、非模板函数test的匹配规则
test的两个重载是明确的非模板函数:
void test(std::string && x):参数是右值引用,只能接收右值(比如临时对象、std::move处理后的左值)。void test(const std::string & x):参数是const左值引用,可以兼容左值、const左值、右值三种类型。
变量y是std::string&类型的左值,无法匹配右值引用的重载,只能选择const std::string&版本,因此输出test: 2。
二、模板函数test2的匹配规则
test2的两个重载是模板函数,核心差异在于template<typename T> void test2(T&& x)不是普通的右值引用,而是转发引用(万能引用),它的参数推导规则特殊:
- 当传入左值(比如
y)时,模板参数T会被推导为左值引用类型——这里就是std::string&。 - 根据C++的引用折叠规则:
T&&即std::string& &&会折叠成std::string&(左值引用)。 - 此时
test2(T&&)实例化后的函数是void test2(std::string& x),另一重载是void test2(const std::string& x)。 - 对于非const的左值
y,test2(std::string&)比test2(const std::string&)匹配优先级更高(不需要给左值添加const限定),因此调用该版本,输出test2: 1。
内容的提问来源于stack exchange,提问作者otto sleger
相关产品推荐
相关产品推荐

