我有一些带有访问功能的类,如下所示:
struct Person {
std::string name;
unsigned age;
template<class Visitor>
void visit(Visitor& c)
{
c("name", name);
c("age", age);
}
template<class Visitor>
void visit(Visitor& c) const
{
c("name", name);
c("age", age);
}
};
我有一个访客,例如:
struct PrintVisitor
{
PrintVisitor(std::ostream& stream)
: m_stream(stream)
{}
template<class T>
void operator()(const std::string& name, const T& v)
{
m_stream << name << ": " << v << std::endl;
}
private:
std::ostream& m_stream;
};
对于每个访问者,我想定义一个流操作符:
std::ostream& operator<<(std::ostream& stream, const Person& p)
{
PrintVisitor printer(stream);
p.visit(printer);
return stream;
}
是否可以提供一个接受任何 Visitable 类的 operator<<?
(现在,我只是在尝试打印,但我实际上想实现 json 序列化、反序列化,也许还有相等和小于运算符。
更新
我使用大卫解决方案:
CRTP 的基类:
template <class T>
struct Visitable {};
所有可访问的类都从那里继承:
struct Person : Visitable<Person> { ... }
运算符和函数是这样模板化的,并使用静态转换来访问类:
template<class T>
std::ostream& operator<<(std::ostream& stream, const Visitable<T>& p)
{
PrintVisitor printer(stream);
static_cast<const T&>(p).visit(printer);
return stream;
}