You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何传递const右值时C++模板函数匹配结果与《C++ Primer》不符?

关于C++模板函数匹配const右值的疑惑

测试代码

#include <iostream>
#include <string>
#include <utility>
using namespace std;

template<typename T>
void func(T&& t){
    cout << "T&&" << endl;
}
template<typename T>
void func(const T& t){
    cout << "const T&" << endl;
}
int main() {
    const string s1 = "b";
    func(std::move(s1));
    return 0;
}

运行结果

T&&

《C++ Primer》中文版相关描述

// Template function binding to non-const rvalue
template <typename T> void f(T&&);
// Template function binding to lvalue and const rvalue
template <typename T> void f(const T&)

正如非模板函数一样,第一个版本绑定到可修改的右值,而第二个版本绑定到左值或const右值。

问题分析

这里的核心是模板参数推导、引用折叠规则以及函数重载的匹配优先级:

  • 传递std::move(s1)时,表达式类型是const string&&(s1是const string,std::move将其转为const右值引用)。
  • 第一个模板func(T&&)中,模板参数T会被推导为const string,经引用折叠后参数类型就是const string&&,和实参类型完全匹配。
  • 第二个模板func(const T&)中,模板参数T会被推导为string,参数类型是const string&,虽然const string&&可以隐式绑定到const string&,但这种属于转换匹配,优先级远低于第一个模板的完全匹配。

所以编译器会优先选择第一个模板,和你看到的运行结果一致。

《C++ Primer》的描述存在语境限制:它大概率是在对比非模板函数的重载逻辑——非模板的void f(T&&)确实只能绑定非const右值,void f(const T&)可以绑定左值和const右值,但模板中的T&&是万能引用,推导规则和非模板右值引用完全不同,能匹配包括const右值在内的所有值类别,这时就得看匹配的精确程度来选择重载版本。

内容的提问来源于stack exchange,提问作者scFei

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 03:33:17