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

调用引用类型的函数模板重载:Clang拒接GCC/MSVC接受,谁符合C++标准?

函数模板重载的编译器分歧:哪个符合C++标准?

我编写了一个包含重载函数模板的程序,Clang编译报错,但GCC和MSVC能正常编译运行。

#include <utility>
#include <iostream>
template< class T > void f( T& t ){} ;
template< class T > void f( const T&& ) {};
int main()
{
    int i = 0;
    f<int&>(i); // Clang: 编译报错,GCC/MSVC: 正常通过
} 

Clang的报错信息如下:

<source>:10:5: error: call to 'f' is ambiguous
   10 |     f<int&>(i); //clang:nope, gcc:ok, msvc:ok
      |     ^~~~~~~
<source>:4:26: note: candidate function [with T = int &]
    4 | template< class T > void f( T& t ){} ;
      |                          ^
<source>:5:26: note: candidate function [with T = int &]
    5 | template< class T > void f( const T&& ) {};
      |        

根据C标准,Clang的处理是正确的,原因如下:
当显式指定模板参数T=int&时,结合C
的引用折叠规则与引用类型的cv限定规则,两个模板会被实例化为完全相同的函数签名:

  1. 第一个模板void f(T&):T&展开为int& &,根据引用折叠规则,左值引用叠加后仍为左值引用,最终签名为void f(int&)。
  2. 第二个模板void f(const T&&):C++标准规定引用类型不能被const/volatile限定,因此const T(其中T=int&)等价于int&;再结合引用折叠规则,int& &&会折叠为int&,最终签名同样是void f(int&)。

两个实例化后的函数完全一致,调用时必然存在歧义,Clang的报错完全符合标准。GCC和MSVC的编译通过属于非标准的宽松处理,不符合规范要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 21:42:48