Я хотел бы использовать boost.variant<T0,T1,T2>
в качестве параметра для класса шаблона «Посетитель», который будет предоставлять операторов посетителей в соответствии с требованиями механизма посетителей boost.variant, в этом случае все возвращают void, т.е.
void operator()(T0 value);
void operator()(T1 value);
void operator()(T2 value);
Шаблон также будет иметь для каждого из типов T0... в варианте соответствующую виртуальную функцию, которая по умолчанию ничего не делает. Пользователь может наследоваться от класса-шаблона и переопределять только те виртуальные функции, которые ему интересны. Это что-то вроде известного паттерна «Шаблонный метод». Единственное решение, которое мне удалось придумать, — это обернуть boost::variant и связанного с ним посетителя в один шаблон и получить к ним доступ через typedefs. Это работает нормально, однако кажется немного неуклюжим. Вот код:
#include "boost/variant.hpp"
//create specializations of VariantWrapper for different numbers of variants -
//just show a template for a variant with three types here.
//variadic template parameter list would be even better!
template<typename T0, typename T1, typename T2>
struct VariantWrapper
{
//the type for the variant
typedef boost::variant<T0,T1,T2> VariantType;
//The visitor class for this variant
struct Visitor : public boost::static_visitor<>
{
void operator()(T0 value)
{
Process(value);
}
void operator()(T1 value)
{
Process(value);
}
void operator()(T2 value)
{
Process(value);
}
virtual void Process(T0 val){/*do nothing */}
virtual void Process(T1 val){/*do nothing */}
virtual void Process(T2 val){/*do nothing */}
protected:
Visitor(){}
};
typedef Visitor VisitorType;
private:
VariantWrapper(){}
};
Затем класс используется следующим образом:
typedef VariantWapper<bool,int,double> VariantWrapperType;
typedef VariantWrapperType::VariantType VariantType;
typedef VariantWrapperType::VisitorType VisitorType;
struct Visitor : public VisitorType
{
void Process(bool val){/*do something*/}
void Process(int val){/*do something*/}
/* this class is not interested in the double value */
};
VariantType data(true);
apply_visitor(Visitor(),data);
Как я уже сказал, кажется, что это работает нормально, но я бы предпочел, чтобы мне не нужно было создавать специальный класс-оболочку, чтобы связать вариант и посетителя вместе. Я бы предпочел иметь возможность просто использовать boost.variant напрямую для создания экземпляра класса посетителя шаблона. Я рассмотрел использование параметров типа, параметров, не являющихся типом, и параметров шаблона шаблона, но, похоже, ничего не напрашивается. То, что я пытаюсь сделать, невозможно? Я могу что-то упустить, и был бы признателен, если бы кто-нибудь что-то сказал по этому поводу.