boost::static_visitor 作为地图值
boost::static_visitor as Map Value
我正在尝试为 boost::static_visitor
的整数创建查找 table
using VariableValue = boost::variant<int, double, std::string>;
struct low_priority {};
struct high_priority : low_priority {};
struct Mul : boost::static_visitor < VariableValue>{
template <typename T, typename U>
auto operator() (high_priority, T a, U b) const -> decltype(VariableValue(a * b)) {
return a * b;
}
template <typename T, typename U>
VariableValue operator() (low_priority, T, U) const {
throw std::runtime_error("Incompatible arguments");
}
template <typename T, typename U>
VariableValue operator() (T a, U b) const {
return (*this)(high_priority{}, a, b);
}
};
const std::map < int, boost::static_visitor<VariableValue> > binopHelper = {
{1, Mul{}}
};
但是当我执行以下操作时:
std::cout << (VariableValue)boost::apply_visitor(binopHelper.at(1), (VariableValue)2, (VariableValue)4) << std::endl;
我收到错误:
term does not evaluate to a function taking 2 arguments (compiling source file interpreter.cpp)
我怎样才能使 static_visitor 接受 2 个参数来匹配 Mul
的参数?
你会 slicing。你需要动态分配。最快的方法是使用类型擦除。
诀窍是想出一个固定的静态已知原型。在这种情况下,二元函数就是它,您可以将 apply_visitor
调度添加到 Mul
对象:
#include <boost/variant.hpp>
#include <functional>
#include <iostream>
#include <map>
using VariableValue = boost::variant<int, double>;
struct Mul : boost::static_visitor<VariableValue> {
struct high_priority{};
struct low_priority{};
auto operator() (VariableValue const& a, VariableValue const& b) const {
return boost::apply_visitor(*this, a, b);
}
template <typename T, typename U>
auto operator() (high_priority, T a, U b) const -> decltype(VariableValue(a * b)) {
return a * b;
}
template <typename T, typename U>
VariableValue operator() (low_priority, T, U) const {
throw std::runtime_error("Incompatible arguments");
}
template <typename T, typename U>
VariableValue operator() (T a, U b) const {
return (*this)(high_priority{}, a, b);
}
};
const std::map < int, std::function<VariableValue(VariableValue const&, VariableValue const&)> > binopHelper = {
{1, Mul{}}
};
int main() {
VariableValue i(42), d(3.1415926);
std::cout << binopHelper.at(1)(i, d) << "\n";
std::cout << binopHelper.at(1)(d, i) << "\n";
}
打印:
131.947
131.947
额外的想法
您似乎正在实施表达式求值。你可以做得更简单,例如重新使用标准库。我在这里有一个相当广泛的演示:https://github.com/sehe/qi-extended-parser-evaluator/blob/master/eval.h#L360 It was developed on [SO] in a chat discussion here: https://chat.whosebug.com/transcript/210289/2020/3/25
有什么想知道的可以问我
具体来说,那里的代码展示了如何在适当的时候处理类型不匹配和隐式 bool 转换。
我正在尝试为 boost::static_visitor
的整数创建查找 tableusing VariableValue = boost::variant<int, double, std::string>;
struct low_priority {};
struct high_priority : low_priority {};
struct Mul : boost::static_visitor < VariableValue>{
template <typename T, typename U>
auto operator() (high_priority, T a, U b) const -> decltype(VariableValue(a * b)) {
return a * b;
}
template <typename T, typename U>
VariableValue operator() (low_priority, T, U) const {
throw std::runtime_error("Incompatible arguments");
}
template <typename T, typename U>
VariableValue operator() (T a, U b) const {
return (*this)(high_priority{}, a, b);
}
};
const std::map < int, boost::static_visitor<VariableValue> > binopHelper = {
{1, Mul{}}
};
但是当我执行以下操作时:
std::cout << (VariableValue)boost::apply_visitor(binopHelper.at(1), (VariableValue)2, (VariableValue)4) << std::endl;
我收到错误:
term does not evaluate to a function taking 2 arguments (compiling source file interpreter.cpp)
我怎样才能使 static_visitor 接受 2 个参数来匹配 Mul
的参数?
你会 slicing。你需要动态分配。最快的方法是使用类型擦除。
诀窍是想出一个固定的静态已知原型。在这种情况下,二元函数就是它,您可以将 apply_visitor
调度添加到 Mul
对象:
#include <boost/variant.hpp>
#include <functional>
#include <iostream>
#include <map>
using VariableValue = boost::variant<int, double>;
struct Mul : boost::static_visitor<VariableValue> {
struct high_priority{};
struct low_priority{};
auto operator() (VariableValue const& a, VariableValue const& b) const {
return boost::apply_visitor(*this, a, b);
}
template <typename T, typename U>
auto operator() (high_priority, T a, U b) const -> decltype(VariableValue(a * b)) {
return a * b;
}
template <typename T, typename U>
VariableValue operator() (low_priority, T, U) const {
throw std::runtime_error("Incompatible arguments");
}
template <typename T, typename U>
VariableValue operator() (T a, U b) const {
return (*this)(high_priority{}, a, b);
}
};
const std::map < int, std::function<VariableValue(VariableValue const&, VariableValue const&)> > binopHelper = {
{1, Mul{}}
};
int main() {
VariableValue i(42), d(3.1415926);
std::cout << binopHelper.at(1)(i, d) << "\n";
std::cout << binopHelper.at(1)(d, i) << "\n";
}
打印:
131.947
131.947
额外的想法
您似乎正在实施表达式求值。你可以做得更简单,例如重新使用标准库。我在这里有一个相当广泛的演示:https://github.com/sehe/qi-extended-parser-evaluator/blob/master/eval.h#L360 It was developed on [SO] in a chat discussion here: https://chat.whosebug.com/transcript/210289/2020/3/25
有什么想知道的可以问我
具体来说,那里的代码展示了如何在适当的时候处理类型不匹配和隐式 bool 转换。