HC4*_*ica 12 c++ function-object overload-resolution c++11
在重载解析期间,函数对象是否与常规函数区别对待?如果是这样,怎么样?
我遇到了以下情况:用等效可调用函数对象替换函数改变了代码的含义:
#include <iostream>
namespace N
{
enum E { A, B };
void bar(E mode) { std::cout << "N::bar\n"; }
}
template <typename... Args>
void bar(Args&&... args) { std::cout << "global bar\n"; }
int main()
{
bar(N::A);
}
Run Code Online (Sandbox Code Playgroud)
这里的输出是"N :: bar".到目前为止,非常好:ADL找到N :: bar,N :: bar和全局条都是精确匹配,N :: bar是首选,因为它不是模板.
但是如果我将全局条改变为函数对象,就像这样:
#include <iostream>
namespace N
{
enum E { A, B };
void bar(E mode) { std::cout << "N::bar\n"; }
}
struct S
{
template <typename... Args>
void operator()(Args&&... args) { std::cout << "global bar\n"; }
};
S bar;
int main()
{
bar(N::A);
}
Run Code Online (Sandbox Code Playgroud)
输出现在是"全球酒吧".为什么不同?
Dav*_*eas 12
这里重要的一点是,如果查找确定名称是函数调用中的函数,则ADL仅启动.在第二种情况下,bar发现是一个对象而不是一个函数,因此表达式bar(N::A)不是函数调用,而是operator()对象的应用bar.因为它不是函数调用,所以ADL不会启动并且N::bar不会被考虑.
3.4.1/3
查找用作函数调用的后缀表达式的非限定名称在3.4.2中描述.[注意:为了确定(在解析期间)表达式是否是函数调用的后缀表达式,通常的名称查找规则适用.3.4.2 [ADL]中的规则对表达式的句法解释没有影响.
查看它的另一种方法是注意ADL将向重载函数集添加新函数,但在第二个示例中没有这样的集合:lookup查找对象并调用对象的成员.
| 归档时间: |
|
| 查看次数: |
152 次 |
| 最近记录: |