为什么依赖于参数的查找不适用于默认参数?

Why doesn't argument dependent lookup work with default arguments?

我写了以下代码一半期望默认参数触发 ADL。它没有(我得到了一个编译器错误)。
触发 ADL 是否需要显式参数?

#include <iostream>

namespace sheldon
{
    enum FLAG{ USA , UK , EU };

    void fun( FLAG f = USA )
    {
        std::cout << "Fun with flags!" << std::endl;
    }
}

int main()
{
    fun();  // Does not compile
    // fun( sheldon::USA ); // compiles
}

ADL 仅适用于您提供的参数,否则事情会非常糟糕,命名空间在隔离其内容时变得毫无用处。
想想如果你也有这个会发生什么:

namespace fun {
    struct tag {};
    void fun(tag = {})
    {
        std::cout << "Fun with tags!" << std::endl;
    }
}

我们可以玩旗帜或标签吗?

当编译器遇到函数调用表达式时,它首先构建一个可能调用函数的重载集,然后执行重载解析。 ADL 是重载集生成的一部分。
现在,当谈到这个声明时:

fun();

首先,它在全局命名空间中查找可能的重载。它找到 none.
然后它根据参数 passed 执行 ADL,但你没有传递任何参数。
因此重载集为空。

以下函数调用:

fun();

不包含任何参数,因此无法触发依赖于参数的查找。

为了澄清,"arguments" 指的是调用函数时实际传递的 values/references,而不是 "parameters",后者是函数在中指定的 names/types它的声明。