添加调试工具以增强变体访问者
Adding debugging facilities to boost variant visitor
我在整个项目中都在使用 boost-variant
,我认为它是 boost
中最有用、最通用的工具之一。
但是如果复杂地使用具有递归嵌套变体的访问者模式,调试有时会很麻烦。
因此我决定实施一个可重复使用的 DebugVisitor
,它可能会添加到我现有的访问者中。如果出现缺陷,我现有的访问者应该很容易 added/removed。
易于移除意味着它应该可以添加到任何现有的访问者 class,而不是修改使用访问者实例的地方。
我试图找到符合我要求的解决方案。以下代码可以编译,但不幸的是它没有打印消息。
有人知道为什么吗?
#include <iostream>
#include <boost/variant.hpp>
#include <functional>
template<typename V> // V must have the boost::static_visitor Interface
struct DebugVisitor : public V {
template<typename U>
typename V::result_type operator()(const U& u) const {
std::cout << "Visiting Type:" << typeid(U).name() << " with Visitor: " << typeid(V).name() << std::endl;
return V::operator()(u);
}
};
struct AddVisitor : public DebugVisitor<boost::static_visitor<boost::variant<int, double>>> {
template<typename U>
result_type operator()(const U& u) const {
return u + 1.;
}
};
int main(int, char**) {
boost::variant<double, int> number{ 3.2 };
AddVisitor d;
auto incr=number.apply_visitor(d);
if (auto dValue = boost::get<double>(incr)) {
std::cout << "Increment: " << dValue << std::endl;
}
return 0;
}
您看不到调试输出的原因是 AddVisitor::operator()
没有调用 DebugVisitor::operator()
。如果是这样,您将在尝试解析 boost::static_visitor<>::operator()
时出错, 不存在 。
选项 1。
只是在AddVisitor
的定义中条件编译调试
struct AddVisitor : public boost::static_visitor<boost::variant<int, double>> {
template<typename U>
result_type operator()(const U& u) const {
#ifdef DEBUG
std::cout << "Visiting Type:" << typeid(U).name() << " with Visitor: " << typeid(AddVisitor).name() << std::endl;
#endif
return u + 1.;
}
};
选项 2。
有条件地定义要被DebugVisitor
包裹的符号AddVisitor
template<typename V> // V must have the boost::static_visitor Interface
struct DebugVisitor : public V {
template<typename U>
typename V::result_type operator()(const U& u) const {
std::cout << "Visiting Type:" << typeid(U).name() << " with Visitor: " << typeid(V).name() << std::endl;
return V::operator()(u);
}
};
struct AddVisitorBase : public boost::static_visitor<boost::variant<int, double>> {
template<typename U>
result_type operator()(const U& u) const {
return u + 1.;
}
};
#ifdef DEBUG
using AddVisitor = DebugVisitor<AddVisitorBase>;
#else
using AddVisitor = AddVisitorBase;
#endif
选项 3.
一对CRTP碱基
template<typename V> // V must have the boost::static_visitor Interface
struct DebugVisitor : public V {
template<typename U>
typename V::result_type operator()(const U& u) const {
std::cout << "Visiting Type:" << typeid(U).name() << " with Visitor: " << typeid(V).name() << std::endl;
return V::call(u);
}
};
template<typename V> // V must have the boost::static_visitor Interface
struct NotDebugVisitor : public V {
template<typename U>
typename V::result_type operator()(const U& u) const {
return V::call(u);
}
};
struct AddVisitor : public boost::static_visitor<boost::variant<int, double>>, public
#ifdef DEBUG
DebugVisitor<AddVisitor>
#else
NotDebugVisitor<AddVisitor>
#endif
{
template<typename U>
result_type call(const U& u) const {
return u + 1.;
}
};
我在整个项目中都在使用 boost-variant
,我认为它是 boost
中最有用、最通用的工具之一。
但是如果复杂地使用具有递归嵌套变体的访问者模式,调试有时会很麻烦。
因此我决定实施一个可重复使用的 DebugVisitor
,它可能会添加到我现有的访问者中。如果出现缺陷,我现有的访问者应该很容易 added/removed。
易于移除意味着它应该可以添加到任何现有的访问者 class,而不是修改使用访问者实例的地方。
我试图找到符合我要求的解决方案。以下代码可以编译,但不幸的是它没有打印消息。
有人知道为什么吗?
#include <iostream>
#include <boost/variant.hpp>
#include <functional>
template<typename V> // V must have the boost::static_visitor Interface
struct DebugVisitor : public V {
template<typename U>
typename V::result_type operator()(const U& u) const {
std::cout << "Visiting Type:" << typeid(U).name() << " with Visitor: " << typeid(V).name() << std::endl;
return V::operator()(u);
}
};
struct AddVisitor : public DebugVisitor<boost::static_visitor<boost::variant<int, double>>> {
template<typename U>
result_type operator()(const U& u) const {
return u + 1.;
}
};
int main(int, char**) {
boost::variant<double, int> number{ 3.2 };
AddVisitor d;
auto incr=number.apply_visitor(d);
if (auto dValue = boost::get<double>(incr)) {
std::cout << "Increment: " << dValue << std::endl;
}
return 0;
}
您看不到调试输出的原因是 AddVisitor::operator()
没有调用 DebugVisitor::operator()
。如果是这样,您将在尝试解析 boost::static_visitor<>::operator()
时出错, 不存在 。
选项 1。
只是在AddVisitor
struct AddVisitor : public boost::static_visitor<boost::variant<int, double>> {
template<typename U>
result_type operator()(const U& u) const {
#ifdef DEBUG
std::cout << "Visiting Type:" << typeid(U).name() << " with Visitor: " << typeid(AddVisitor).name() << std::endl;
#endif
return u + 1.;
}
};
选项 2。
有条件地定义要被DebugVisitor
AddVisitor
template<typename V> // V must have the boost::static_visitor Interface
struct DebugVisitor : public V {
template<typename U>
typename V::result_type operator()(const U& u) const {
std::cout << "Visiting Type:" << typeid(U).name() << " with Visitor: " << typeid(V).name() << std::endl;
return V::operator()(u);
}
};
struct AddVisitorBase : public boost::static_visitor<boost::variant<int, double>> {
template<typename U>
result_type operator()(const U& u) const {
return u + 1.;
}
};
#ifdef DEBUG
using AddVisitor = DebugVisitor<AddVisitorBase>;
#else
using AddVisitor = AddVisitorBase;
#endif
选项 3.
一对CRTP碱基
template<typename V> // V must have the boost::static_visitor Interface
struct DebugVisitor : public V {
template<typename U>
typename V::result_type operator()(const U& u) const {
std::cout << "Visiting Type:" << typeid(U).name() << " with Visitor: " << typeid(V).name() << std::endl;
return V::call(u);
}
};
template<typename V> // V must have the boost::static_visitor Interface
struct NotDebugVisitor : public V {
template<typename U>
typename V::result_type operator()(const U& u) const {
return V::call(u);
}
};
struct AddVisitor : public boost::static_visitor<boost::variant<int, double>>, public
#ifdef DEBUG
DebugVisitor<AddVisitor>
#else
NotDebugVisitor<AddVisitor>
#endif
{
template<typename U>
result_type call(const U& u) const {
return u + 1.;
}
};