boost :: static_visitor с несколькими аргументами

typedef boost::variant<int, double> Type;
class Append: public boost::static_visitor<>
{
public:
void operator()(int)
{}

void operator()(double)
{}

};

Type type(1.2);
Visitor visitor;
boost::apply_visitor(visitor, type);

Можно ли изменить посетителя так, чтобы он получал дополнительные данные следующим образом:

class Append: public boost::static_visitor<>
{
public:
void operator()(int, const std::string&)
{}

void operator()(double, const std::string&)
{}
};

Это строковое значение изменяется в течение времени жизни объекта Append. Передача строки через конструктор в этом случае невозможна.

10

Решение

«Дополнительным аргументом», который получают каждый вызов, является this указатель. Используйте его для передачи любой дополнительной информации, которая вам нужна:

#include <boost/variant.hpp>
typedef boost::variant<int, double> Type;
class Append: public boost::static_visitor<>
{
public:
void operator()(int)
{}

void operator()(double)
{}
std::string argument;
};

int main() {
Type type(1.2);
Append visitor;
visitor.argument = "first value";
boost::apply_visitor(visitor, type);
visitor.argument = "new value";
boost::apply_visitor(visitor, type);
}
15

Другие решения

Другой вариант — связать дополнительные аргументы. Ваш класс посетителя может выглядеть так:

class Append: public boost::static_visitor<>
{
public:
void operator()(const std::string&, int)
{}

void operator()(const std::string&, double)
{}
};

Назовите это так:

std::string myString = "foo";
double value = 1.2;
auto visitor = std::bind( Append(), myString, std::placeholders::_1 );
boost::apply_visitor( visitor, value );
1