我想从其他访问者的内部呼叫访问者。请考虑以下代码:
struct visitor1 : boost::static_visitor<>
{
void operator()(const int& i) const { std::cout << "visitor1:" << i; }
void operator()(const std::string & str) const { std::cout << "visitor1, string: " << str}
};
struct visitor2 : boost::static_visitor<>
{
void operator()(const int& i) const
{
// apply visitor1 here
boost::apply_visitor(visitor1(), /* is there a context reference to the variant here? */)
std::cout << "visitor 2 applied visitor 1";
}
void operator()(const std::string & str) const { //... }
};
int main()
{
boost::variant< int, std::string> v = 5;
boost::apply_visitor(visitor2 (), v );
}
应输出:
visitor1: 5
Visitor 2 applied visitor 1
答案 0 :(得分:3)
如果您想要使用该变体,只需直接调用它(无需使用apply_visitor)。
如果您想另外,只需使用bind
或类似内容:
<强> Live On Coliru 强>
#include <boost/variant.hpp>
#include <boost/bind.hpp>
#include <iostream>
struct visitor1 : boost::static_visitor<>
{
void operator()(const int& i) const { std::cout << "visitor1:" << i << "\n"; }
void operator()(const std::string & str) const { std::cout << "visitor1, string: " << str << "\n"; }
};
struct visitor2 : boost::static_visitor<>
{
template <typename Variant>
void operator()(const int& i, Variant const& v) const
{
boost::apply_visitor(visitor1(), v);
std::cout << "visitor 2 applied visitor 1" << " (int " << i << ")\n";
}
template <typename Variant>
void operator()(const std::string & str, Variant const& v) const {
boost::apply_visitor(visitor1(), v);
std::cout << "visitor 2 applied visitor 1" << " (string " << str << ")\n";
}
};
int main()
{
using V = boost::variant< int, std::string>;
for (V v : { V{5}, V{"something"} })
boost::apply_visitor(boost::bind(visitor2(), _1, boost::ref(v)), v);
}
打印
visitor1:5
visitor 2 applied visitor 1 (int 5)
visitor1, string: something
visitor 2 applied visitor 1 (string something)
如果你喜欢DIY,你可以轻松地模仿“绑定”:
<强> Live On Coliru 强>
template <typename V>
struct visitor2 {
typedef void result_type;
V const* _ref;
void operator()(const int& i) const {
boost::apply_visitor(visitor1(), *_ref);
std::cout << "visitor 2 applied visitor 1" << " (int " << i << ")\n";
}
void operator()(const std::string & str) const {
boost::apply_visitor(visitor1(), *_ref);
std::cout << "visitor 2 applied visitor 1" << " (string " << str << ")\n";
}
};
int main()
{
using V = boost::variant< int, std::string>;
for (V v : { V{5}, V{"something"} })
boost::apply_visitor(visitor2<V>{&v}, v);
}
打印
visitor1:5
visitor 2 applied visitor 1 (int 5)
visitor1, string: something
visitor 2 applied visitor 1 (string something)
我喜欢让函数对象Variant-aware,然后你可以隐藏“双重绑定”:
<强> Live On Coliru 强>
struct visitor2 {
typedef void result_type;
template <typename... Ts>
void operator()(boost::variant<Ts...> const& v) const {
return boost::apply_visitor(boost::bind(*this, _1, boost::cref(v)), v);
}
template <typename Variant>
void operator()(const int& i, Variant const& v) const {
boost::apply_visitor(visitor1(), v);
std::cout << "visitor 2 applied visitor 1" << " (int " << i << ")\n";
}
template <typename Variant>
void operator()(const std::string & str, Variant const& v) const {
boost::apply_visitor(visitor1(), v);
std::cout << "visitor 2 applied visitor 1" << " (string " << str << ")\n";
}
};
int main()
{
using V = boost::variant< int, std::string>;
for (V v : { V{5}, V{"something"} })
visitor2{}(v);
}
打印
visitor1:5
visitor 2 applied visitor 1 (int 5)
visitor1, string: something
visitor 2 applied visitor 1 (string something)