为什么编译器会在模板参数列表中选择基类构造函数?
这个问题的后续问题.
基本上,在下面的代码中,为什么编译器认为C
的构造函数中A
里面的B
是指B
基类的(不可访问的)构造函数?
Basically, in the following code, why does the compiler think that the B
inside A<B>
in C
s constructor refer to the (inaccessible) constructor of the B
base class?
struct B{};
template <typename T>
struct A : private T{};
struct C : public A<B>{
C(A<B>); // ERROR HERE
};
Ideone 上的实例. 输出:
prog.cpp:1:9: 错误:'struct B B::B' 不可访问
prog.cpp:7:7: 错误:在此上下文中
prog.cpp:1:9: error: 'struct B B::B' is inaccessible
prog.cpp:7:7: error: within this context
请注意,如果您将构造函数参数更改为 A<B*>
、A<B&>
甚至 A<;const B>
.还要注意 MSVC10、GCC 4.7 和 Clang 3.1 ToT 中的三个会出错,所以它必须是 C++ 规范中的内容.是什么?
Note that the same error pops up if you change the constructor argument to A<B*>
, A<B&>
or even A<const B>
. Also note that three of MSVC10, GCC 4.7 and Clang 3.1 ToT will error out, so it must be something in the C++ spec. What is it?
推荐答案
该标准允许注入的类名比原始名称更难访问.甚至在 §11.1/5 的注释中也提到了这一点,并附有示例:
The standard allows injected class names to be less accessible than the original names. This is even mentioned in a note in §11.1/5, together with an example:
[ 注意: 在派生类中,查找基类名称会在中找到注入的类名而不是基类的名称声明它的范围.注入的类名可能是比其作用域中的基类名称更难访问它被宣布.―结束注释 ]
[ Note: In a derived class, the lookup of a base class name will find the injected-class-name instead of the name of the base class in the scope in which it was declared. The injected-class-name might be less accessible than the name of the base class in the scope in which it was declared. ―end note ]
[ 示例:
class A { };
class B : private A { };
class C : public B {
A *p; // error: injected-class-name A is inaccessible
::A *q; // OK
};
―结束示例 ]
访问 A
不合格使用注入的名称,该名称不可访问,因为它来自私有继承.访问 A
限定使用声明的名称,该名称可在全局范围内访问.
Accessing A
unqualified uses the injected name, which is not accessible because it comes from private inheritance. Accessing A
qualified uses the declared name, which is accessible in the global scope.
相关文章