c++ - boost::static_visitor 作为地图值
问题描述
我正在尝试为 ints 创建一个查找表到 boost::static_visitor
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;
我得到错误:
术语不计算为带 2 个参数的函数(编译源文件解释器.cpp)
我怎样才能使 static_visitor 需要 2 个参数来匹配Mul
?
解决方案
你会切片的。您需要动态分配。最快的方法是使用类型擦除。
诀窍是想出一个固定的静态已知原型。在这种情况下,它将是一个二进制函数,您可以将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它是在 [SO] 上在此处的聊天讨论中开发的:https: //chat.stackoverflow.com/transcript/210289/2020/3/25
如果您想了解更多信息,请随时问我。
具体来说,那里的代码显示了如何在适当的情况下处理类型不匹配和隐式 bool 转换。
推荐阅读
- python - vscode python调试器不对断点或stoponentry做出反应
- c++ - “标识符未定义”,试图从私有结构创建一个函数
- django - Django 将图像从 URL 保存到模型导致 UnicodeDecodeError: 'utf-8' codec can't decode byte 0xff in position 0: invalid start byte
- if-statement - SAS 错误:SUM 的空参数无效
- python - 使用 Python 通过目录中的多个 .csv 文件循环函数
- jupyter-notebook - 谷歌colab中的数据集丢失了?
- python - 使用前一个日期从现有列创建新的 Pandas 列
- apache-spark - 关于 spark 数据集中的 count 方法的问题?
- mysql - 我如何知道是什么促使自动 MYSQL 查询每天在我的网站上运行?
- google-sheets - 在 Google 表格中加入两个表并计算第二个表中的值