c++ - boost::static_visitor 作为映射值

标签 c++ templates boost overriding static-visitor

我正在尝试为 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;

我收到错误:

term does not evaluate to a function taking 2 arguments (compiling source file interpreter.cpp)

如何才能使 static_visitor 采用 2 个参数来匹配 Mul 的参数?

最佳答案

你会是slicing 。您需要动态分配。最快的方法是使用类型删除。

诀窍是提出一个固定的静态已知原型(prototype)。在这种情况下,一个二进制函数就是它,您可以将 apply_visitor 调度添加到 Mul 对象:

<强> Live On Coliru

#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 转换。

关于c++ - boost::static_visitor 作为映射值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61564623/

相关文章:

c++ - 被连续迭代的线程安全无序映射

c++ - CGAL 错误:计算没有给定点的半空间交集无法编译(boost::none?)

c++ - boost optional 和 std::experimental optional assignment 之间的区别

c++ - 将 boost 多精度与三角函数结合使用

c++ - 在 C++11 中逐列迭代 2D 和 3D vector ?

c++ - C++ 中的 nullptr 和 nullptr_t 有什么区别?

c++ - 字符串流中的行尾

c++ - 非常基础的英语语法解析器

c++ - 将内部函数作为模板参数传递

c++11:字符串文字的恒定时间查找函数