我觉得我在这里遗漏了一些明显的东西,但我有一个班级宣布另一个班级为朋友,但似乎无法访问其私人会员。
我已将问题最小化如下:
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
^~~
请注意,我声明WidgetBase
和WidgetDerived
都是Foo
的朋友。我在这里缺少什么?
答案 0 :(得分:2)
这是一个GCC(G ++)错误,请参阅bug report。代码使用clang 6.0.0编译得很好。但是,clang 5.0.0也拒绝该代码。
不幸的是,我只能建议这两种可能的解决方案。 1)使结构公开,或2)使用最新版本的clang进行编译。