Bar*_*ett 46 c++ templates language-lawyer
为什么类D编译,但类C没有?
class A
{
public:
A(int) {}
};
template <class T>
class B : private T // Note: private base class
{
public:
using T::T;
};
class C : public B<A>
{
public:
C() : B<A>(123) {} // Error: 'class A A::A' is inaccessible
}; // within this context
using BA = B<A>;
class D : public BA
{
public:
D() : BA(123) {} // OK
};
Run Code Online (Sandbox Code Playgroud)
我用GCC,Clang和Visual C++ 进行了测试,它们都是一样的.改变class B : private T以public T解决问题.但为什么?(注意using T::T是public.)
Rei*_*ica 42
类在其范围内A包含inject-class-name A(即,除非碰巧引用构造函数,否则A::A引用类A).
类B继承这一点,所以名称A的范围内B是指在注射类名A中的范围A.但是,由于A是私有基类B,因此范围内的所有名称A都是私有的B.
类C再次继承了这个,但它无法访问它A,因为它是私有的B.因此错误.请注意,错误实际上是使用A构造中的名称B<A>.
类BA没有这个问题,因为定义B<A>不在任何类的范围内,所以名称A是指全局名称A而不是任何注入类名.当然,这个名字BA是公开的.
您可以通过A在C以下位置限定名称来轻松解决此问题:
class C : public B<A>
{
public:
C() : B<::A>( 123 ) {}
};
Run Code Online (Sandbox Code Playgroud)
请注意,构造函数继承在那里没有效果.问题是与访问类名A(注入A和继承中B和C),不进入的构造.