gpt4 book ai didi

c++ - 转发 boost::variant 从一个访问者到另一个

转载 作者:搜寻专家 更新时间:2023-10-31 01:35:49 26 4
gpt4 key购买 nike

我想从另一个访问者内部调用一个访问者的 boost 变体。考虑以下代码:

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

最佳答案

如果你想采用变体,直接调用它(witout 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)

没有绑定(bind)的替代方案

如果您喜欢 DIY,您可以轻松模拟“绑定(bind)”:

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)

风格注释:

我喜欢让函数对象变体感知,然后你可以隐藏“双重绑定(bind)”:

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)

关于c++ - 转发 boost::variant 从一个访问者到另一个,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36682454/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com