为什么编译器选择模板参数列表中的基类构造函数? [英] Why does the compiler select the base class constructor inside the template argument list?

查看:145
本文介绍了为什么编译器选择模板参数列表中的基类构造函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

后续问题要这一个



基本上,在下面的代码中,编译器为什么认为 B A $ c> C 的构造函数是指 B 基类的(不可访问)构造函数


$ b b

  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 BB :: B'无法访问

prog.cpp:7:7:错误:在此上下文中


请注意, A< B *> A 或甚至 A< const B> 。还要注意,MSVC10,GCC 4.7和Clang 3.1 ToT中的三个会出错,所以它必须是C ++规范中的一些东西。 是什么?

解决方案

标准允许注入的类名称比原始名称。这甚至在§11.1/ 5的注释中提到,连同一个例子:


[在派生类中,基类名称的查找将

中找到注入类名,而不是基类的名称,在其中声明它。 inject-class-name可能比在声明
的作用域中的基类的名称
更不可访问。



< p $ p> class A {};
class B:private A {};
class C:public B {
A * p; //错误:inject-class-name A是不可访问的
:: A * q; // OK
};

- end example ]


< blockquote>

访问 A 不合格使用注入的名称,这是不可访问的,因为它来自私人继承。访问 A 限定使用已声明的名称,可在全局范围中访问。


Follow-up question to this one.

Basically, in the following code, why does the compiler think that the B inside A<B> in Cs 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
};

Live example on Ideone. Output:

prog.cpp:1:9: error: 'struct B B::B' is inaccessible
prog.cpp:7:7: error: within this context

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?

解决方案

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 ]

[ Example:

class A { };
class B : private A { };
class C : public B {
  A *p; // error: injected-class-name A is inaccessible
  ::A *q; // OK
};

end example ]

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.

这篇关于为什么编译器选择模板参数列表中的基类构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆