【问题标题】:Does Argument-Dependent Lookup go before normal scope lookup?依赖于参数的查找是否在正常范围查找之前进行?
【发布时间】:2018-03-28 16:10:03
【问题描述】:

这是出现在“C++ Primer”第 5 节第 13.3 节中的相关代码:

void swap(Foo &lhs, Foo &rhs)
{
    using std::swap;
    swap(lhs.h, rhs.h); // uses the HasPtr version of swap
    // swap other members of type Foo
}

书中提到了特定于类的交换没有被 using 声明隐藏的现象,并请读者参考 §18.2.3:

我阅读了该部分并意识到这可能与依赖于参数的查找 (ADL) 有关。以下为节选:

但是我的理解还是有些模糊。我的问题是:ADL 是在正常范围查找之前进行还是在正常范围查找之后进行?我目前的理解是 ADL 在正常范围查找之前进行,否则它应该是使用的 std::swap 。如果您认为我是对的,我需要确认,或者如果您认为我错了,请指出我犯了什么错误。谢谢。

【问题讨论】:

    标签: c++ scope namespaces argument-dependent-lookup using-declaration


    【解决方案1】:

    ADL先不去,不是特别喜欢;除了通常的名称查找找到的名称之外,还将考虑 ADL 找到的名称。

    除了通常的非限定名称查找所考虑的范围和名称空间之外,还会在其参数的名称空间中查找这些函数名称。

    这意味着所有通过 ADL 找到的名称和通常的名称查找都将在 overload resolution 中考虑;然后将选择最佳匹配。

    为了编译一个函数调用,编译器必须首先执行名称查找,对于函数,可能涉及依赖于参数的查找,对于函数模板,可能之后是模板参数推导。如果这些步骤产生了多个候选函数,则执行重载决策以选择实际调用的函数。

    【讨论】:

    • 谢谢。所以不隐藏的关键原因是过载。作者应该同时提到 §18.2.3 和 §18.2.4。如果std命名空间恰好有一个HasPtr版本的swap,那么std::swap会成功隐藏在外部范围中定义的用户定义的swap,对吧?
    • @user5280911 如果您仍然有原始过载,那么调用将是模棱两可的。如果不是,那么是的,非模板 sts::swap 将被调用
    • 嗨,Rakete1111,感谢您的 cmets。我在这里发布了一个关于这个方向的后续问题:stackoverflow.com/questions/46785093/…。你能看看吗?谢谢大家!
    • 似乎泛型函数和类型特定函数都参与了在重载决议发生时可行的函数。哪个重载解决规则阻止选择通用的而不是类型特定的?因为是函数模板?(or, if not that, F1 is a non-template function while F2 is a template specialization) 如果不是规则,还有其他规则吗?使特定类型的函数功能更好匹配的规则是什么?
    • @rosshjb 是的,非模板函数在相同条件下是可以使用的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-08
    • 2012-07-22
    • 1970-01-01
    • 2016-03-24
    相关资源
    最近更新 更多