我有以下 CRTP 类,我想用它们来实现访问者模式
template <class Derived>
class Visitor
{
public:
Visitor() {
static_assert(!std::is_same<Visitor, Derived>::value,
"Visitor class cannot be instantiated directly. Use a derived class.");
}
virtual ~Visitor() = default;
virtual void visit(Derived&) = 0;
};
template <class Derived>
class Visitable
{
friend void Visitor<Derived>::visit(Derived&);
public:
Visitable() {
static_assert(!std::is_same<Visitable, Derived>::value,
"Visitable class cannot be instantiated directly. Use a derived class.");
}
template <class T>
void accept(T& visitor)
{
visitor.visit(static_cast<Derived &>(*this));
}
};
然后我定义一个可访问的类
class Data : public Visitable<Data>
{
private:
std::string foo;
};
以及班级的访客
class Printer : public Visitor<Data>
{
void visit(Data& data)
{
std::cout << data.foo << std::endl;
};
};
但是编译器告诉我“foo 是‘Data’的私有成员”......为什么我的朋友规范不能按预期工作?
我也尝试将“朋友”移动到派生类,但并没有解决问题。
class Data : public Visitable<Data>
{
friend void Visitor<Data>::visit(Data&); // instead of in Visitable
private:
std::string foo;
};