C++ 使用私有继承的限定名的行为

C++ 使用私有继承的限定名的行为,c++,inheritance,C++,Inheritance,在msvc中编译以下示例时,我得到 “接口”不可访问,因为“基”使用“私有”来 从“接口”继承 在标有错误的行中。当对foo的调用使用同一类型的类型别名进行限定时,它会起作用。我用msvc和ideone进行了测试 为什么这两个电话不相等 struct Interface {}; template<class T> struct Base : private T { void foo() {} }; using BaseX = Base<Interface>

在msvc中编译以下示例时,我得到

“接口”不可访问,因为“基”使用“私有”来 从“接口”继承

在标有
错误的行中
。当对
foo
的调用使用同一类型的类型别名进行限定时,它会起作用。我用msvc和ideone进行了测试

为什么这两个电话不相等

struct Interface {};

template<class T>
struct Base : private T
{
    void foo() {}
};

using BaseX =   Base<Interface>;

class Derived : Base<Interface>
{
    Derived() {
        Base<Interface>::foo();   // Error
        BaseX::foo();             // Works
    }
};
struct接口{};
模板
结构基:私有T
{
void foo(){}
};
使用BaseX=Base;
派生类:基
{
派生的(){
Base::foo();//错误
BaseX::foo();//有效
}
};
注入的类名

名称
接口
被注入类
接口
的作用域,就好像它是公共成员一样,然后由
继承(作为私有成员,因为您使用的是私有继承)

Derived
中编写
Base::foo()
时,
Interface
的非限定名称查找首先查看
Derived
及其基类,在基类中查找
Interface
,然后启动访问控制,因为该名称是
private

最简单的修复方法是只写
Base::foo()
,或者如果它不是虚拟的,并且您不打算在
派生的
中写
foo()
,甚至只写
foo()


如果出于某种原因必须包含模板参数,那么写
Base

看起来像msvcbug@DieterL我用g++4.9.3和
BaseX::foo()进行了尝试有效。我们为什么要查找
接口
呢?@Barry-Um,你写了
Base::foo()
…不知道为什么你认为它不会被查找。@Barry好吧,在我们查找
foo
之前,我们需要知道查找它的范围(或者,什么是
Base
)。所以你要查找
Base
Interface
。不幸的是,我继承了几个
Base
,需要
Base:
来消除歧义。对于这种情况,最优雅的解决方案是什么?@BetaCarotin限定名称。