为什么 `static_pointer_cast` 不能与 ADL 一起工作,而是需要显式的 `std::`?

Why doesn't `static_pointer_cast` work with ADL, but requires explicit `std::`?

考虑

// https://godbolt.org/z/z5M9b9jzx
#include <memory>
#include <cassert>

struct B {};
struct D : B {};

int main() {
    std::shared_ptr<B> b = std::make_shared<D>();
    auto d = static_pointer_cast<D>(b);
    assert(d);
}

我本以为对 static_pointer_cast 的不合格调用会解析为 std::static_pointer_cast,因为 b 作为 std::shared_ptr,应该会带来 namespace std 在使用 ADL 中。

为什么不呢?我需要明确地写 std::shared_pointer_cast 才能让它工作。

https://en.cppreference.com/w/cpp/language/adl

Although a function call can be resolved through ADL even if ordinary lookup finds nothing, a function call to a function template with explicitly-specified template arguments requires that there is a declaration of the template found by ordinary lookup (otherwise, it is a syntax error to encounter an unknown name followed by a less-than character) (until C++20)

在 C++20 模式下,您的代码可以正常编译,演示:https://gcc.godbolt.org/z/b13q4hs68