gpt4 book ai didi

c++ - 编译器如何在下面的代码中通过ADL找到模板函数X::max(T const&, T const&)?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:39:28 24 4
gpt4 key购买 nike

感谢 Standard 的引述。

#include <iostream>

namespace X {
class A {};
}

template <typename T>
inline T const& max(T const& a, T const& b, T const& c)
{
return max(max(a, b), c);
}

inline X::A const& max(X::A const& a, X::A const& b)
{
std::cout << "non-template" << '\n';
return a;
}

int main()
{
X::A a, b, c;
max(a, b, c);
}

namespace X {
template <typename T>
inline T const& max(T const& a, T const& b)
{
std::cout << "template" << '\n';
return a;
}
}

Live example

最佳答案

标准语

调用max()在示例中需要一个从属名称,因为它的参数取决于模板参数 T .此类从属名称的两阶段名称查找在标准中定义如下:

14.6.4.2 候选函数 [temp.dep.candidate]

1 For a function call where the postfix-expression is a dependent name, the candidate functions are found using the usual lookup rules (3.4.1, 3.4.2) except that:

— For the part of the lookup using unqualified name lookup (3.4.1), only function declarations from the template definition context are found.

— For the part of the lookup using associated namespaces (3.4.2), only function declarations found in either the template definition context or the template instantiation context are found.

非限定查找定义为

3.4.1 非限定名称查找 [basic.lookup.unqual]

1 In all the cases listed in 3.4.1, the scopes are searched for a declaration in the order listed in each of the respective categories; name lookup ends as soon as a declaration is found for the name. If no declaration is found, the program is ill-formed.

和参数依赖查找(ADL)作为

3.4.2 参数相关名称查找[basic.lookup.argdep]

1 When the postfix-expression in a function call (5.2.2) is an unqualified-id, other namespaces not considered during the usual unqualified lookup (3.4.1) may be searched, and in those namespaces, namespace-scope friend function or function template declarations (11.3) not otherwise visible may be found. These modifications to the search depend on the types of the arguments (and for template template arguments, the namespace of the template argument).

为什么你的代码失败了

在您的示例中,非限定查找和 ADL 都没有发现任何重载在定义点,因为编译器没有看到任何双参数 max()然而。 ADL 也适用于在实例化时,那时,编译器已经看到了两个参数 template max(T, T)这是唯一可以调用的。 (区别在于模板实例化发生在整个翻译单元被解析之后)。

更好的代码

您应该通过放置非模板 max(X::A, X::A) 来修复您的代码namespace X 内部过载并移动 template max(T, T)

#include <iostream>

// generic code

template <typename T>
inline T const& max(T const& a, T const& b)
{
std::cout << "template" << '\n';
return a;
}

template <typename T>
inline T const& max(T const& a, T const& b, T const& c)
{
using ::max; // fallback if no user-defined max
return max(max(a, b), c);
}

// X specific code

namespace X {

class A {};

inline X::A const& max(X::A const& a, X::A const& b)
{
std::cout << "non-template" << '\n';
return a;
}

} // namespace X

int main()
{
X::A a, b, c;
max(a, b, c);
}

Live-Example打印“非模板”两次。

关于c++ - 编译器如何在下面的代码中通过ADL找到模板函数X::max(T const&, T const&)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24533091/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com