C++ 如果函数获取指向该类的指针,则该函数将完全从候选列表中删除
如果一个非成员函数碰巧也有一个指向类的指针,为什么不能有一个与成员函数同名的非成员函数呢 这不会编译: 结构FooConfig{int value;}; struct BarConfig{int value;}; 类Api { void configureconst FooConfig&cfg; void configureconst BarConfig&cfg; }; //助手 静态无效配置API*自身,int值 { //实际执行 } void Api::configureconst FooConfig&cfg { configuratis,cfg.value; } void Api::configureconst BarConfig&cfg { configuratis,cfg.value; } Gcc和Clang都在骗我,说没有一个名为configure的函数接受2个参数 有趣的是: 如果我只是用self指针重命名helper函数,或者让它接受一个引用而不是指针,那么它突然就存在了,一切都很好 顺便说一句,在名称查找中,成员函数的巧合相似性并不重要。我是在愚弄C++吗?< /p> < p>试试C++ 如果函数获取指向该类的指针,则该函数将完全从候选列表中删除,c++,name-lookup,C++,Name Lookup,如果一个非成员函数碰巧也有一个指向类的指针,为什么不能有一个与成员函数同名的非成员函数呢 这不会编译: 结构FooConfig{int value;}; struct BarConfig{int value;}; 类Api { void configureconst FooConfig&cfg; void configureconst BarConfig&cfg; }; //助手 静态无效配置API*自身,int值 { //实际执行 } void Api::configureconst FooC
::configure(this, cfg.value);
试一试
尝试在成员函数中调用configure时,在类作用域(即成员函数)中找到名称configure,然后停止,将不检查全局作用域的进一步作用域;无法找到全局配置,它被成员函数隐藏
名称查找按如下所述检查作用域,直到找到至少一个任何类型的声明,此时查找停止,不再检查其他作用域
作为解决方案,您可以指定全局解决方案为::configuratis,cfg.value 尝试在成员函数中调用configure时,在类作用域(即成员函数)中找到名称configure,然后停止,将不检查globle作用域的进一步作用域;无法找到全局配置,它被成员函数隐藏
名称查找按如下所述检查作用域,直到找到至少一个任何类型的声明,此时查找停止,不再检查其他作用域
作为解决方案,您可以指定全局解决方案为::configuratis,cfg.value 在重载解析选择最佳可行函数之前,将形成一组候选函数,具体匹配被调用方的名称。为此,将使用名称查找过程 表达式configuratis,cfg.value是类成员函数作用域内的非限定调用,为此,名称查找过程将在首次使用之前首先在该函数块本身中搜索声明,如果未找到,则遍历该类及其基类,并且仅当仍未找到时,它将访问封闭的名称空间。也就是说,当使用这个搜索范围的有序层次结构时,它将在第一次声明时停止 在上述过程的第2阶段中,loopkup过程的名称将查找Api::configure的两个overalod,这将形成重载解析的候选集。由于两者都不接受两个参数,编译器将正确诊断错误 为了从全局命名空间强制使用函数,请使用::configuratis,cfg.value。这指示应在哪个命名空间中搜索configure的声明 如果我[…]让它接受一个引用而不是指针,那么它就会突然存在,一切都会好起来
这是不可能的,因为这不会影响名称查找过程。但是,更改名称是可行的。在重载解析选择最佳可行函数之前,将形成一组候选函数,特别是与被调用方的名称相匹配的函数。为此,将使用名称查找过程 表达式configuratis,cfg.value是类成员函数作用域内的非限定调用,为此,名称查找过程将在首次使用之前首先在该函数块本身中搜索声明,如果未找到,则遍历该类及其基类,并且仅当仍未找到时,它将访问封闭的名称空间。也就是说,当使用这个搜索范围的有序层次结构时,它将在第一次声明时停止 在上述过程的第2阶段中,loopkup过程的名称将查找Api::configure的两个overalod,这将形成重载解析的候选集。由于两者都不接受两个参数,编译器将正确诊断错误 为了从全局命名空间强制使用函数,请使用::configuratis,cfg.value。这指示应在哪个命名空间中搜索configure的声明 如果我[…]让它接受一个引用而不是指针,那么它就会突然存在,一切都会好起来
这是不可能的,因为这不会影响名称查找过程。但是,更改名称会导致错误。::configuratis,cfg.value;哇!我希望编译器能告诉我这一点。我会接受这个答案。超载ap
在同一范围内定义的函数的层。API有两个名为configure的成员函数,它们被重载。全局名称空间中的另一个对象与其他两个对象不在同一范围内定义,因此编译器不会查找它。编译器可能会猜测您打算使用全局函数,但当有六个全局函数时,或者当您不打算使用全局函数而只是错误地键入了其中一个参数时,您会发现一个警告:configuratis,cfg.value;哇!我希望编译器能告诉我这一点。我接受这个答案。重载适用于在同一范围内定义的函数。API有两个名为configure的成员函数,它们被重载。全局名称空间中的另一个对象与其他两个对象不在同一范围内定义,因此编译器不会查找它。编译器可能会猜测您打算使用全局函数,但是当有六个全局函数时,或者当您不打算使用全局函数而只是错误地键入了其中一个参数时,您会发现一个警告,这非常令人讨厌。