我尝试使用模板实现访问者模式。
我的code是:
struct some_class
{
char field1;
bool field2;
some_class()
: field1('a')
, field2(0)
{
}
};
struct unnamed_lambda
{
template<typename T>
T operator()(T x) const { return x + 1; }
};
struct unnamed_lambda2
{
template<typename T>
T operator()(T x) const { return x + 2; }
};
template<class processor>
void reflect(processor & p, some_class& sc)
{
reflect(p, sc.field1, "field1");
reflect(p, sc.field2, "field2");
}
template<class t>
void reflect(unnamed_lambda & p, t& val, string str)
{
cout << val << endl;
}
void print_helper()
{
unnamed_lambda lambda = unnamed_lambda{};
some_class sc;
reflect(lambda, sc);
}
template<class t>
void reflect2(unnamed_lambda2 & p, t& val, string str)
{
cout << val + 1 << endl;
}
void print_helper2()
{
unnamed_lambda2 lambda = unnamed_lambda2{};
some_class sc;
reflect(lambda, sc);
}
int main()
{
print_helper();
print_helper2();
return 0;
}
我希望有一些类定义其字段的遍历顺序。在我的例子中,它是void reflect(processor & p, some_class& sc)
函数。另外,我想在这个课上有一系列的动作。就我而言,它是print_helper
和print_helper2
。
为了关联操作和所需的操作,我创建了两个哑结构:unnamed_lambda
和unnamed_lambda2
。这些结构什么都不做。这是一种解决方法。
为什么这段代码闻起来如此糟糕?有一个原因。签名函数void reflect(processor & p, some_class& sc)
是固定的。
换句话说,除了更改此函数的签名及其实现之外,我可以做任何事情。更多我无法更改some_class
类。
答案 0 :(得分:1)
略过中间步骤。您的访问者应该访问:
template<class processor>
void reflect(processor & p, some_class& sc)
{
p(sc.field1, "field1");
p(sc.field2, "field2");
}
访客可能是:
struct visitor {
template <typename T>
void operator()(T& field, const std::string& name) {
std::cout << "value of '" << name << "' = " << field << '\n';
}
};
some_class sc;
visitor v;
reflect(v, sc);