【发布时间】:2011-07-04 09:46:57
【问题描述】:
我最近在使用私有继承方案时遇到了一个问题,其中基类定义了一个模板方法,而(私有)派生类通过 public 访问说明符下的 using 声明将该方法公开。该模板旨在获取函数的地址并调用该函数指针。但是,在尝试将函数名称传递给派生类模板方法时,我收到一条错误消息,指出基类方法无法访问派生类中声明的私有成员。这是一个模拟问题的代码段:
class A
{
public:
template<class T> void Funct(T pFunct) { }
};
class B : private A
{
public:
using A::Funct;
};
void Show(void) { }
int main(void)
{
B b;
b.Funct(Show);
}
准确的错误消息是:'A::Funct' : cannot access private member declared in class 'B'
我可以通过以下方式解决问题:
1)在函数参数名称前加上地址运算符:
b.Funct(&Show);
2)显式限定模板类型参数:
b.Funct<void(*)(void)>(Show)
如果Show() 函数也是模板,我需要使用用于实例化Show 的正确模板类型参数显式限定模板。
我的问题不是如何解决问题,而是为什么会生成错误消息。为什么用Show 和&Show 实例化Funct() 会导致编译器做两件不同的事情。为什么用Show 实例化Funct() 会导致Funct() 方法尝试访问B 类中的私有数据(我假设它是B 类中的A 子对象)?
【问题讨论】:
-
什么编译器?你的例子用 g++ 4.2 编译得很好。
-
有趣。我正在使用 Microsoft Visual C++ 2010
-
这是视觉工作室吗?一些旧版本的模板参数中的成员函数指针存在问题。
-
是的,是VC。那么可能是某种错误?
-
使用 Intellisense,如果没有
&Show或明确指定void(*)(void)作为类型,VC 不知道模板的正确类型。如果您有&Show,当您将鼠标悬停在Funct<void(*)(void)>上时,Intellisense 将正确地将其显示为完全限定的函数。
标签: c++ templates function inheritance private