【发布时间】:2012-08-14 13:15:04
【问题描述】:
我有一些带有访问功能的类,如下所示:
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 类的操作符
(现在,我只是在尝试打印,但实际上我想实现 json 序列化、反序列化以及可能的相等和小于运算符。
更新
我使用了 Davids 解决方案:
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;
}
【问题讨论】:
-
我在解析“是否有可能不必在模板函数中只实现一次运算符”时遇到困难