вариант буста с пользовательскими классами

я пытался boost-variant с пользовательских классов. Я понял, что безопасный способ доступа к содержимому класса — это использование boost::static_visitor, Знаете ли вы, почему приведенный ниже код не компилируется? Существуют ли какие-либо требования к подписи / декларации boost::static_visitor чтобы быть использованным?

Я нашел этот вопрос Почему я не могу посетить этот пользовательский тип с Boost :: Вариант? но я не понял

С уважением

AFG

#include <iostream>
#include <algorithm>
#include <boost/variant.hpp>

struct CA{};

struct ca_visitor : public boost::static_visitor<CA>
{
const CA& operator()(const CA& obj ) const { return obj;}
};

struct CB{};

struct cb_visitor : public boost::static_visitor<CB>
{
const CB& operator()(const CB& obj) const { return obj;}
};

int main(){
typedef  boost::variant<
CA
,CB >  v_type;

v_type v;
const CA& a = boost::apply_visitor( ca_visitor(), v );
}

2

Решение

Прежде всего, аргумент шаблона boost::static_visitor<> следует указать тип, возвращаемый оператором вызова. В твоем случае, ca_visitorоператор вызова возвращает CA const&не CA,

Но это не самая большая проблема. Самая большая проблема заключается в том, что вы, похоже, неправильно понимаете, как variant<> а также static_visitor<> должно сработать.

Идея boost::variant<> является то, что он может содержать значения любой из типов, указанных в списке аргументов шаблона. Вы не знаете, что это за тип, и поэтому вы предоставляете посетителю несколько перегруженных операторов вызова для обработки каждого возможного случая.

Поэтому, когда вы предоставляете посетителю, вы должны убедиться, что он имеет все необходимые перегрузки operator() которые принимают типы ваших variant может держать. Если вы этого не сделаете, Boost.Variant приведет к генерации ошибки компиляции (и делает вам одолжение, потому что вы забыли обработать некоторые случаи).

Это проблема, с которой вы сталкиваетесь: у вашего посетителя нет оператора вызова, принимающего объект типа CB,

Это пример правильного использования boost::variant<> а также static_visitor<>:

#include <iostream>
#include <algorithm>
#include <boost/variant.hpp>

struct A{};
struct B{};

struct my_visitor : public boost::static_visitor<bool>
//                                               ^^^^
//                                               This must be the same as the
//                                               return type of your call
//                                               operators
{
bool operator() (const A& obj ) const { return true; }
bool operator() (const B& obj) const { return false; }
};

int main()
{
A a;
B b;
my_visitor mv;

typedef boost::variant<A, B> v_type;

v_type v = a;

bool res = v.apply_visitor(mv);
std::cout << res; // Should print 1

v = b;

res = v.apply_visitor(mv);
std::cout << res; // Should print 0
}
4

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

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector