Я пытаюсь создать функцию посетителя, которая будет складывать значения моего boost::variant
. Я использую шаблоны для случая, когда типы отличаются, например int + float
typedef boost::variant<int, float> Values;
struct Add : public boost::static_visitor<Values> {
template <typename T, typename U>
auto operator() (T a, U b) const -> decltype(a + b) {
return a + b;
}
}
Это компилируется и отлично работает
std::cout << boost::apply_visitor(Add{}, (Values)2, (Values)5) << std::endl;
std::cout << boost::apply_visitor(Add{}, (Values)2, (Values)5.123) << std::endl;
7
7.123
Однако я также хочу добавить std::string
в вариант Values
, чтобы я также мог сложить вместе строки. Я знаю, что, например, string + int
сделать невозможно, но я постараюсь, чтобы оба из Values
были строкой, прежде чем пытаться пропустить их через посетителя.
typedef boost::variant<int, float, std::string> Values;
std::cout << boost::apply_visitor(Add{}, (Values)"hello", (Values)"world") << std::endl;
Однако программа не компилируется, выдавая ошибку:
Не удалось специализировать шаблон функции 'неизвестный тип Add :: operator () (T, U) const'
Я знаю, что std::string
является объектом, а не типом, и поэтому эта ошибка имеет смысл, поэтому я пытаюсь сделать особый случай, перегружая operator
в структуре Add
, когда входные данные являются обеими строками :
auto operator() (std::string a, std::string b) const {
return a + b;
}
Однако я получаю ошибку
std :: basic_string, std :: allocator> Add :: operator () (std :: string, std :: string ) const ': невозможно преобразовать аргумент 1 из' T 'в' std :: string '
Похоже, он все еще пытается запустить строковый аргумент через шаблонного посетителя. Куда я иду не так? Есть ли лучший способ достичь того, что я пытаюсь сделать в целом? Извините, если ответ очевиден, я все еще довольно плохо знаком с C ++, Boost и шаблонами.