【问题标题】:Why does the compiler select the base class constructor inside the template argument list?为什么编译器会选择模板参数列表中的基类构造函数?
【发布时间】:2012-03-02 15:59:17
【问题描述】:

向this one提出后续问题。

基本上,在下面的代码中,为什么编译器会认为Cs构造函数中A<B>里面的B引用了B基类的(不可访问的)构造函数?

struct B{};

template <typename T>
struct A : private T{};

struct C : public A<B>{                                                                             
    C(A<B>);   // ERROR HERE
};

Live example on Ideone. 输出:

prog.cpp:1:9: 错误:'struct B B::B' 不可访问
prog.cpp:7:7: 错误:在此上下文中

请注意,如果将构造函数参数更改为A&lt;B*&gt;、A&lt;B&amp;&gt; 甚至A&lt;const B&gt;,则会弹出相同的错误。另请注意,MSVC10、GCC 4.7 和 Clang 3.1 ToT 中的三个将出错,因此它必须是 C++ 规范中的内容。 这是什么?

【问题讨论】:

  • 我不知道您为什么创建完全相同的主题!您可以编辑该主题以使其成为更好的主题。
  • @Nawaz:这是一个根本不同的问题。我问“为什么”,另一个问题是“做什么”。
  • 伙计,我不止一次被class A : private NotCopyable { class B : private NotCopyable {} }; 咬过。我猜它在查看全局范围之前先在类范围内查找符号。
  • @Xeo:这就是为什么我说您可以编辑该主题以使其变得更好。
  • @AndréCaron:那个特定的例子编译得很好。

标签: c++ templates scope c++11 base-class


【解决方案1】:

该标准允许注入的类名称比原始名称更难访问。这甚至在第 11.1/5 节的注释中提到,并附有一个示例:

[ 注意: 在派生类中,基类名称的查找将 找到注入的类名而不是基类的名称 声明它的范围。注入的类名可能是 比其范围内的基类名称更难访问 它被宣布。 ——尾注 ]

[例子:

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

—结束示例 ]

访问A unqualified 使用注入的名称,该名称不可访问,因为它来自私有继承。访问 A 限定使用声明的名称,该名称可在全局范围内访问。

【讨论】:

    猜你喜欢
    • 2017-10-01
    • 2012-03-26
    • 2017-07-20
    • 1970-01-01
    • 2017-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-25
    相关资源
    最近更新 更多