阶级友谊和继承问题

时间:2018-05-14 20:03:13

标签: c++

我觉得我在这里遗漏了一些明显的东西,但我有一个班级宣布另一个班级为朋友,但似乎无法访问其私人会员。

我已将问题最小化如下:

Widget.hpp

template<typename T> class Foo;

template<typename T, typename U>
class WidgetBase
{
protected:
    T* ptr;
public:
    WidgetBase(T* ptr) : ptr{ptr} {}
    virtual void f() = 0;
};

template<typename T>
class WidgetDerived : public WidgetBase<typename Foo<T>::Bar, T>
{
public:
    using WidgetBase<typename Foo<T>::Bar, T>::WidgetBase;
    using WidgetBase<typename Foo<T>::Bar, T>::ptr;
    virtual void f() { ptr->x = 9; }
};


Foo.hpp

#include "Widget.hpp"

template<typename T>
class Foo
{
private:
    struct Bar
    {
        T x;
        explicit Bar(T x) : x{x} {}
    };
public:
    Bar* bar;
    explicit Foo(T x) : bar{new Bar{x}} {}
    ~Foo() { delete bar; }
    WidgetDerived<T> foo_widget() { WidgetDerived<T> widget{bar}; return widget; }
    friend class WidgetBase<Bar, T>;
    friend class WidgetDerived<T>;
};


的main.cpp

#include "Foo.hpp"

int main()
{
    Foo<int> foo(7);
    auto widget = foo.foo_widget();
}

使用GCC 7.3.0,我尝试使用:g++ -o main main.cpp -pedantic -Wall -Werror -Wconversion -std=c++1z进行编译并收到以下错误消息:

In file included from Foo.hpp:1:0,
                 from main.cpp:1:
Widget.hpp: In instantiation of 'class WidgetDerived<int>':
main.cpp:6:34:   required from here
Widget.hpp:14:7: error: 'struct Foo<int>::Bar' is private within this context
 class WidgetDerived : public WidgetBase<typename Foo<T>::Bar, T>
       ^~~~~~~~~~~~~
In file included from main.cpp:1:0:
Foo.hpp:7:12: note: declared private here
     struct Bar
            ^~~


请注意,我声明WidgetBaseWidgetDerived都是Foo的朋友。我在这里缺少什么?

1 个答案:

答案 0 :(得分:2)

这是一个GCC(G ++)错误,请参阅bug report。代码使用clang 6.0.0编译得很好。但是,clang 5.0.0也拒绝该代码。

不幸的是,我只能建议这两种可能的解决方案。 1)使结构公开,或2)使用最新版本的clang进行编译。