- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
感谢 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;
}
}
最佳答案
调用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/
这个问题在这里已经有了答案: How do I write an ADL-enabled trailing return type, or noexcept specification? (4 个答
例如,我想使用约束来确保函数 isinf为模板参数实现 T .如 T是 float 之一, double , long double或整数类型,这可以通过以下方式完成: #include templ
我在 ADF 中进行自定义事件,其中涉及从 Azure 存储 Blob 读取多个文件,对它们进行一些处理,然后最终将生成的文件写入 Azure Data Lake Store。最后一步是我停止的地方,
我遇到了以下涉及 ADL 和已删除函数的令人困惑的示例: 第一个例子: namespace A { struct S{}; void f(S){cout << "adl" << end
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
template struct S { bool valid(T a) { return is_valid(a); } }; bool is_valid(int) { return t
我有几个命名空间,每个命名空间都有一个名为 f 的函数模板。 // f() and Widget namespace A { struct Widget { }; template vo
我有一个带有类内定义友元函数的类,我最好不要修改它(它来自已经部署的 header ) #include #include namespace our_namespace { template
我有一个函数模板 printSize 在声明 getSize 之前调用重载函数 getSize。为了让我的程序结构更清晰,我想将两个函数放在不同的命名空间 A 和 B 中,如注释代码行所示。但是,AD
struct S { vector v; void method() { begin(v); } }; 上面的代码片段编译正常,因为 ADL直到我添加
对于非限定名称查找,“通常非限定名称查找”和“参数相关名称查找”(ADL),我无法在标准中找到哪一个先发生? 再次尝试向过载候选集添加一些内容,但顺序似乎并不重要。但仍然很高兴知道哪一个先发生。 谢谢
我试图了解如何 ADL至少它的基础是有效的,并创建了以下代码: #include #include #include using std::pair; using std::string; u
简而言之,我试图了解 C++ 中参数依赖查找的行为。我不清楚 ISO/IEC 14882:2017 (E) 中关于 ADL 的一些陈述。我希望有人能向我澄清它们。 按照标准, Typedef name
可以给我一个不使用模板的 ADL 示例吗?从来没有见过这样的东西。我的意思是像 here .具体来说,我对导致上述一些陷阱的示例感兴趣。 编辑: 我认为 Tomalak 的回答可以延伸到陷阱。考虑一下
有3个例子: 我. typedef int foo; namespace B { struct S { operator int(){ return 24; }
我正在使用 Visual Studio 2010 在 Microsoft Windows 7 上编译 x64 服务,使用 Boost variant像这样的东西: namespace my_ns {
情况是某些成员函数 bar::Bar::frobnicate 想要利用 ADL 在具有相同名称的函数中从某个未知命名空间中查找函数。但是,它只能找到自己的名字。 测试用例 (请注意,实际上,Bar 是
我对 C++ 中的标准 ADL 解析有疑问。 这是解释我的查询的示例代码: #include // The mechanism: namespace A { template ::std::st
这是来自 Does argument dependent lookup only search namespaces or classes too? 的跟进问题,其中@David Rodríguez
这个问题在这里已经有了答案: Why doesn't ADL find function templates? (4 个答案) 关闭 8 年前。 我想明白为什么调用模板f下面不编译: struct
我是一名优秀的程序员,十分优秀!