模板化一个简单的Boost Proto C++表达式计算器
Templating a Simple Boost Proto C++ Expression Evaluator
我想在Boost Proto"Unpacking Expressions"示例的基础上,使用模板参数来指定do_eval
转换(迄今为止为double
(的返回类型。
为了简洁起见,我将介绍一个do_eval
:的工作简化(仅限加号(版本
struct do_eval2 : proto::callable
{
typedef double result_type;
template <typename X, typename Y>
result_type operator()(proto::tag::plus, X x, Y y) const { return x + y; }
};
然后我添加了一个模板参数T
而不是double
:
template <typename T>
struct do_eval2 : proto::callable
{
typedef T result_type;
template <typename X, typename Y>
result_type operator()(proto::tag::plus, X x, Y y) const { return x + y; }
};
并将关联的CCD_ 6结构修改为:
struct eval2
: proto::or_<
proto::when<proto::terminal<proto::_>, proto::_value>
, proto::otherwise<do_eval2<double>(proto::tag_of<proto::_>(),
eval2(proto::pack(proto::_))...)>
>
{};
但当我使用它时,如下面的代码所示,我会收到以错误开始的错误:无法将"std::ostream{aka std::basic_stream}"lvalue绑定到"std::basic_stream&;'如何满足编译器的要求?
int main(int argc, char *argv[])
{
int one = 1, two = 2;
cout << eval2()(phoenix::ref(one)+phoenix::ref(two)) << 'n';
return 0;
}
如您所见:
变换通常具有proto::when<Something,R(A0,A1,…(>。问题是R是表示要调用的函数还是表示要构造的对象,答案决定了proto::when<gt;评估变换。proto::when<gt;使用proto::is_callable<gt;消除两者之间歧义的特点。Proto尽力猜测一个类型是否可调用,但它并不总是正确的。最好知道Proto使用的规则,这样你就知道什么时候需要更明确。
对于大多数类型R,proto::is_callable检查proto::callable的继承。但是,如果类型R是模板专用化,Proto会认为它是不可调用的,即使该模板继承自Proto::callable。
该文档提出了解决方案:您可以用proto::call
包装do_eval<double>
的每次调用,也可以简单地将is_callable
专门化到boost::proto命名空间中,然后忘记这个问题。
namespace boost { namespace proto
{
// Tell Proto that do_eval2<> is callable
template<typename T>
struct is_callable<do_eval2<T> >
: mpl::true_
{};
}}
[编辑:]这是proto::call
备选方案:
struct eval2
: proto::or_<
proto::when<proto::terminal<proto::_>, proto::_value>
, proto::otherwise<
proto::call<do_eval2<double>(proto::tag_of<proto::_>(),
eval2(proto::pack(proto::_))...)>>
>
{};
请参阅前面的答案。我还想补充一点,另一个解决方案是这样定义do_eval2
:
template <typename T, typename D = proto::callable>
struct do_eval2 : proto::callable
{
typedef T result_type;
template <typename X, typename Y>
result_type operator()(proto::tag::plus, X x, Y y) const { return x + y; }
};
请注意额外的伪模板参数。
编辑:此外,在目前正在开发的Proto的下一个版本中,你不需要知道这件奥术,一切都应该正常。几周后我将在C++Now上讨论这个问题。
- 理解boost::asio-async_read在无需读取内容时的行为
- boost::进程间消息队列引发错误
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- cmake如何在fedora工作站中找到boost静态库包
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- 如何使用CMake编译.proto文件来生成.grpcp.pb.cc和.grpc.pb.h文件
- Boost Graph Library,修复节点大小
- 什么是"#include <boost/functional/hash.hpp> "?
- boost.proto+从域特定的表达式包装器中打开表达式
- boost.proto+在构建表达式树之前检测无效终端
- boost.proto+就地修改表达式树
- Boost.Proto:具有自定义终端类的EDSL的常规类布局
- 是否可以在Boost.Proto中构建和增量评估/突变表达树
- 用Boost.Proto构建特征表达模板
- boost::proto::is_aggregate为聚合类型时返回false
- 如何使boost-proto函数表达式可流化
- 获取Boost Proto子表达式的标签类型
- 模板化一个简单的Boost Proto C++表达式计算器
- 用boost::proto在c++中编写DSL
- 将Boost.Proto语法与类型匹配