从C ++中的私有模板类继承构造函数 [英] Inheriting a constructor from a private template class in C++
问题描述
为什么类 D
编译,但类 C
不会?
class A
{
public:
A(int){}
};
template< class T>
class B:private T //注意:私有基类
{
public:
使用T :: T;
};
class C:public B< A>
{
public:
C():B< A>(123){} //错误:'A类A :: A'不可访问
}; //在此上下文中
使用BA = B ;
class D:public BA
{
public:
D():BA(123){} // OK
};
我使用GCC测试, Clang 和Visual C ++,它们都是一样的。
将 B类:private T
更改为 public T
可解决问题。但为什么? (注意使用T :: T
是 public
。)
A 包含inject-class-name
A
在其范围内(即 A :: A
是指类 A
,除非它恰巧指向构造函数)
类 B
继承此名称,因此名称 A
范围内的
B
是指范围内的注入类名
。但是,由于 A
A A
是 B
的私有基类,所以 A c
code>再次继承这个,但它不能访问此
A
,因为它是 B
内的私有。因此错误。请注意,错误实际上是在构造 B< A>
中使用名称 A
。
类 BA
没有这个问题,因为 B
不在任何类的范围内,因此 A
的名称指的是全局名称 A
,而不是任何注入类名。当然, BA
是公开的。
您可以通过限定名称 A 在
C
:
class C:public B<
{
public:
C():B <:: A(123){}
};
注意构造函数继承在那里没有效果。问题是访问类名称 A
(注入 A
B
和 C
),无法访问构造函数。
Why does class D
compile, but class C
does not?
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
};
I tested with GCC, Clang and Visual C++, and they are all the same.
Changing class B : private T
to public T
solves the problem. But why? (Note that the using T::T
is public
.)
Class A
contains the injected-class-name A
within its scope (that is, A::A
refers to class A
unless it happens to refer to the constructor).
Class B
inherits this, so the name A
within the scope of B
refers to the injected-class-name A
in scope of A
. However, since A
is a private base class of B
, all names in scope of A
are private within B
.
Class C
again inherits this, but it cannot access this A
, since it is private within B
. Hence the error. Note that the error is actually with using the name A
in the construct B<A>
.
Class BA
doesn't have this problem, since the definition B<A>
is not in the scope of any class, so the name A
refers to the global name A
and not to any injected-class-name. And of course, the name BA
is public.
You can easily solve this by qualifying the name A
in C
:
class C : public B<A>
{
public:
C() : B<::A>( 123 ) {}
};
Note that constructor inheritance has no effect there. The problem is with access to the class name A
(injected in A
and inherited in B
and C
), not with access to the constructor.
这篇关于从C ++中的私有模板类继承构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!