Here是相应的问题,我想知道的是,是否有可能将全局函数引入到成员函数的重载解析中?
我试过两种方法,但两者都行不通:
void foo(double val) { cout << "double\n";}
class obj {
public:
using ::foo; // (1) compile error: using-declaration for non-member at class scope
void callFoo() {
using ::foo; // (2)will cause the global version always be called
foo(6.4);
foo(0);
}
private:
void foo(int val) {cout << "class member foo\n"; }
};发布于 2014-09-16 09:32:58
这是在§3.4.1 basic.lookup.unqual中指定的普通旧的非限定名称查找。
1在3.4.1所列的所有情况下,都会按照各自类别中列出的顺序搜索作用域;一旦找到名称的声明,名称查找就会结束。如果找不到声明,程序就不正确. 8.对于类
X的成员,成员函数体中、默认参数中、异常规范中、非静态数据成员(9.2)的大括号或相等初始化器中使用的名称,或在X定义之外的类成员的定义中,在成员的声明符-id之后使用的名称,应以下列方式之一声明:
X类成员或X基类成员(10.2),或X是类Y (9.7)的嵌套类,则应该是Y的成员,或者是Y基类的成员(此查找依次应用于Y的封闭类,从最内部的封闭类开始),或X是本地类(9.8)或本地类的嵌套类,则在包含类X定义的块中的类X定义之前,或X是名称空间N的成员,或者是属于N成员的类的嵌套类,或者是作为N成员的函数的局部类中的本地类或嵌套类,则在使用名称之前、在名称空间中、在名称空间中或在N的一个封闭名称空间中。注意:首先,一旦找到声明,名称查找就会停止。因此,如果using ::foo;在callFoo()中,查找foo将在那里结束,永远不会触及第二个要点;如果没有,查找foo将在第二个项目点找到成员foo(),而不会在其他地方搜索。指定非限定名查找的方式意味着您将找到类成员或非类成员,但永远不会同时找到两者。
在第13.1.1.1编Over.call.func/p3中也提到了这一点:
在非限定函数调用中,名称不受->或。运算符,并具有更一般形式的主表达式.名称是在函数调用的上下文中查找的,函数调用遵循函数调用中名称查找的常规规则(3.4)。该查找发现的函数声明构成了候选函数的集合。由于名称查找的规则,候选函数集由(1)完全由非成员函数组成,(2)完全由类
T的成员函数组成。在情况(1)中,参数列表与调用中的表达式列表相同。在情况(2)中,参数列表是调用中的表达式列表,通过添加一个隐含的对象参数来增强,就像在限定函数调用中那样。
类作用域中的使用-声明必须命名基类成员(§7.3.3 name pace.udecl/p3):
在用作成员声明的using-声明中,嵌套名称说明符应命名正在定义的类的基类。
发布于 2014-09-16 08:08:23
我怀疑您是否能够使编译器调用一个或另一个基于类型。当然,您可以使用本地包装函数,如下所示:
void callFoo() {
foo(6.4);
foo(0);
}
private:
void foo(double val) { ::foo(val); }包装器函数应该很好地内联为零,因此在用优化编译时没有实际的开销。
或者不要叫成员和全局函数相同的名字,这使生活变得更容易了!
发布于 2014-09-16 08:12:16
您可能无法这样做,可能是因为成员函数具有编译器可见的不同签名,这是
void foo(double)vs
void obj::foo(int)https://stackoverflow.com/questions/25863485
复制相似问题