【问题标题】:clang/g++ difference with private inheritance and using declarationclang/g++ 与私有继承和使用声明的区别
【发布时间】:2015-03-29 05:20:51
【问题描述】:

考虑以下代码:

#include <iostream>

struct Params { };

template <class T>
struct Base
{
    int data() const { return 42; }
};

template <template <class> class D, class P>
struct Middle : private D<P> // must be 'public' for g++
{
};

struct Final : public Middle<Base,Params>
{
    using Base<Params>::data;
};


int main() {

    Final f;

    std::cout << f.data() << std::endl;

    return 0;
}

此代码编译成功并打印42clang 并在gcc 上给出编译时错误

'int Base::data() const [with T = Params]' 不可访问

在这种情况下,哪种实现更符合 C++ 标准?

【问题讨论】:

  • Final 根本不应该看到Base,所以我认为 gcc 在这里获胜?不过,我对自己的回答持谨慎态度,因为在合规性方面我更喜欢 clang...
  • @Aggieboy Final 看到 Base。可访问性!= 可见性。
  • 在将using D&lt;P&gt;::data; 添加到中间类代码后,在 g++ 上编译良好:coliru.stacked-crooked.com/a/269f221d5a8efab8
  • @alexolut 对,因为现在dataMiddle 中是public,这使得Final 可以访问它。
  • @UlrichEckhardt 如果您完全删除模板,clang 会给出与 g++ 相同的错误 goo.gl/aH8ZyY error: 'Base' is a private member of 'Base'

标签: c++ inheritance g++ language-lawyer clang++


【解决方案1】:

GCC 是正确的。 [namespace.udecl]/17:

继承构造函数的访问规则在 12.9 中指定; 否则在 using-declaration 中提及的所有名称实例 应可访问。 特别是,如果派生类使用 using-declaration 访问基类的成员,成员名 应该可以访问。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-26
    • 2018-12-29
    • 1970-01-01
    • 2021-07-07
    • 2016-07-20
    相关资源
    最近更新 更多