c++ - 不考虑参数依赖查找

标签 c++ templates argument-dependent-lookup

<分区>

为什么依赖于参数的查找不考虑 Foo::dynamicCast,它不应该考虑 namespace Foo 因为基类在这个 namespace 中吗?

#include <memory>
using namespace std;

namespace Foo
{

template<typename P, typename T> P*
dynamicCast(T* t)
{
    return dynamic_cast<P*>(t);
}

class Base
{
public:
    virtual ~Base() = default;
};

}

namespace Test
{

class Derived : public Foo::Base
{
};

}

shared_ptr<Foo::Base> b = make_shared<Test::Derived>();
auto d = dynamicCast<Test::Derived>(b.get());

最佳答案

为了理解你有一个带有模板的函数调用,而不是一堆 <>运算符,编译器必须知道你有一个函数模板;为了理解这一点,它必须知道在哪个命名空间中查找它。为了知道这一点,它必须理解函数参数的命名空间。为了理解,它必须知道周围有 函数参数。正如我们所见,这取决于知道有一个函数调用开始。编译器在找到模板声明之前不知道。看到问题了吗?

正因为如此,只有当函数调用中的后缀表达式是一个unqualified-id 时,才会考虑 ADL。哪个dynamicCast<Test::Derived> 不是 只有当dynamicCast已知为 template-name,它是在正常的非限定查找期间确定的,它不会查看声明模板的 namespace 。

作为@T.C.观察到,可以声明一个名为 dynamicCast 的不相关函数模板在全局命名空间中以使 ADL 工作。

在更美好的世界中,我们可以选择编写 template foo<whatever>在任何上下文中并消除尖括号的歧义。也许在 C++20 中。

关于c++ - 不考虑参数依赖查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33921852/

相关文章:

templates - Haskell - 自动使用导入模块中的变量

c++ - 模板类中使用了错误的构造函数

c++ - 为什么此代码会出现错误 "template specialization requires ' template< >'"?

c++ - 具有类参数的函数从命名空间中泄漏?

c++ - 尝试在 qt 中创建访问器函数

c++ - 优先级队列未正确比较 C++

c++ - 没有在 Access-Control-Expose-Headers 中公开自定义 header 值

c++ - 仅重新初始化派生类中的所有成员变量

c++ - const char * 和 const char (& p)[T_Size] 之间的最佳查找匹配

c++ - 在 C++ 中,为什么我可以访问在没有命名空间限定符的命名空间中定义的函数