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

Visual C++中C++20与C++17下Argument-dependent lookup行为差异原因咨询

C20与C17下函数重载决议差异原因

我的程序在Visual Studio的C20模式下运行符合预期,但切换到C17模式时输出发生变化。精简后的代码如下:

template <typename T>
int f() { return g(T{}); }

namespace {
    struct A{
        friend int g(const A &) { return 1; }
    };
}

template <typename T>
int g(T&&) { return 2; }

int main() { return f<A>(); }

在C20模式下main()的返回值为1,而C17模式下返回值为2。


原因分析

这是C++20中由**P1890R0提案(修复纯右值的ADL查找)**带来的规则变更导致的差异:

  • 在C++17中,当调用g(A{})时,A{}是纯右值(prvalue),此时参数依赖查找(ADL)不会将A的友元函数g(const A&)纳入候选函数列表。只有全局的模板函数g(T&&)被找到,推导为g(A&&),因此执行后返回2。
  • 在C++20中,ADL规则被修正:即使参数是纯右值,也会正确查找该类型所在命名空间中的友元函数。此时候选函数有两个:非模板的g(const A&)和模板特化的g(A&&)。根据重载决议的优先级,非模板函数会被优先选择,因此执行后返回1。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:57:17