我正在尝试使用boost::proto和以下终端构建s-expression对象:
typedef proto::terminal< const char* >::type string_term_t;
typedef proto::terminal< uint32_t >::type uint32_term_t;
typedef proto::terminal< float >::type float_term_t;并像这样使用它:
void testInit()
{
auto v = string_term_t("foo") , string_term_t("bla") , (float_term_t(5.6), string_term_t("some"));
proto::display_expr(v);
}然而,这不能为我编译;
Test.cpp:18:33: error: no matching function for call to ‘boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const char*>, 0l>::expr(const char [4])’
boost_1_46_0/boost/proto/proto_fwd.hpp:300:16: note: candidates are: boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const char*>, 0l>::expr()
boost_1_46_0/boost/proto/proto_fwd.hpp:300:16: note: boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const char*>, 0l>::expr(const boost::proto::exprns_::expr<boost::proto::tag::terminal, boost::proto::argsns_::term<const char*>, 0l>&)
Test.cpp:18:33: error: unable to deduce ‘auto’ from ‘<expression error>’
Test.cpp:18:73: error: expected ‘)’ before ‘(’ token我哪里做错了?有什么建议如何使用boost::proto获得与s表达式相似或等价的东西吗?
发布于 2012-04-08 00:30:39
我怀疑您使用this的方式存在一些固有的错误;我刚刚开始阅读它,所以我完全是个新手;不过,下面的代码会编译并执行一些操作
#include <boost/proto/proto.hpp>
using namespace boost;
typedef proto::terminal< const char* >::type string_term_t;
void testInit()
{
auto v = string_term_t ({"foo"});
proto::display_expr(v);
}
int main()
{
testInit();
return 0;
}特别是,我对v的定义中“裸”逗号的用法表示怀疑;我不知道它是否会成为C++11或boost magic的一个新功能,但我不会期望它能像现在这样工作。
添加
经过一小段时间的尝试,我们最终发现逗号操作符是封闭在( )中的一个操作符,而不是“空的”。下面的方法是可行的
typedef proto::terminal< const char* >::type string_term_t;
typedef proto::terminal< uint32_t >::type uint32_term_t;
typedef proto::terminal< float >::type float_term_t;
void testInit()
{
auto v = (string_term_t({"foo"}) , string_term_t({"bla"}) , (float_term_t({5.6}), string_term_t({"some"})));
proto::display_expr(v);
}(为将来的读者编写的;包含{ "foo" }的()或任何可以删除的内容)。
发布于 2012-04-08 04:51:29
proto::expr<>类型没有定义构造函数;因此,您的问题就来了。试着这样定义你的类型:
typedef proto::literal< const char* > string_term_t;
typedef proto::literal< uint32_t > uint32_term_t;
typedef proto::literal< float > float_term_t;发布于 2014-01-05 06:21:13
我在不依赖boost的情况下做了一个编译时的S表达式。唯一的问题是依赖于c++11
sexpr.h
#ifndef S_EXPRESSION_H
#define S_EXPRESSION_H
#include <algorithm>
template< typename... Subexprs > class SExpr;
template< typename SExprType, unsigned int Idx > class SExprGetter;
template< typename SExprType >
class SExprGetter< SExprType, 0 >
{
SExprType* tree;
public:
typedef typename SExprType::Expr_0_type return_type;
SExprGetter(SExprType& _v) : tree(& _v) {}
SExprGetter(SExprGetter&& _o) : tree(_o.tree) {}
return_type& getValue() { return tree->get_storage(); }
template< unsigned int Idx>
SExprGetter< return_type , Idx > getChild()
{
return getValue().template getChild<Idx>();
}
static constexpr unsigned int childs()
{
return return_type::childs();
}
};
template< typename SExprType >
class SExprGetter< SExprType, 1 >
{
SExprType* tree;
typedef typename SExprType::Remainder_type remainder_type_1;
public:
typedef typename remainder_type_1::Expr_0_type return_type;
SExprGetter(SExprType& _v) : tree(& _v) {}
SExprGetter(SExprGetter&& _o) : tree(_o.tree) {}
return_type& getValue() { return tree->get_remainder_storage().get_storage(); }
template< unsigned int Idx>
SExprGetter< return_type , Idx > getChild()
{
return getValue().template getChild<Idx>();
}
static constexpr unsigned int childs()
{
return return_type::childs();
}
};
template< typename SExprType >
class SExprGetter< SExprType, 2 >
{
SExprType* tree;
typedef typename SExprType::Remainder_type remainder_type_1;
typedef typename remainder_type_1::Remainder_type remainder_type_2;
public:
typedef typename remainder_type_2::Expr_0_type return_type;
SExprGetter(SExprType& _v) : tree(& _v) {}
SExprGetter(SExprGetter&& _o) : tree(_o.tree) {}
return_type& getValue() { return tree->get_remainder_storage().get_remainder_storage().get_storage(); }
template< unsigned int Idx>
SExprGetter< return_type , Idx > getChild()
{
return getValue().template getChild<Idx>();
}
static constexpr unsigned int childs()
{
return return_type::childs();
}
};
template< typename SExprType >
class SExprGetter< SExprType, 3 >
{
SExprType* tree;
typedef typename SExprType::Remainder_type remainder_type_1;
typedef typename remainder_type_1::Remainder_type remainder_type_2;
typedef typename remainder_type_2::Remainder_type remainder_type_3;
public:
typedef typename remainder_type_3::Expr_0_type return_type;
SExprGetter(SExprType& _v) : tree(& _v) {}
SExprGetter(SExprGetter&& _o) : tree(_o.tree) {}
return_type& getValue() { return tree->get_remainder_storage().get_remainder_storage().get_remainder_storage().get_storage(); }
template< unsigned int Idx>
SExprGetter< return_type , Idx > getChild()
{
return getValue().template getChild<Idx>();
}
static constexpr unsigned int childs()
{
return return_type::childs();
}
};
template< typename T0, typename... Subexprs >
class SExpr< T0, Subexprs... >
{
T0 _t0_storage;
SExpr< Subexprs... > _remainder_storage;
public:
typedef T0 Expr_0_type;
typedef SExpr< Subexprs... > Remainder_type;
SExpr(T0 _t, Subexprs... sexprs) : _t0_storage(_t), _remainder_storage(sexprs...) {}
SExpr(T0&& _t, Subexprs && ... sexprs) : _t0_storage(_t), _remainder_storage(sexprs...) {}
T0& get_storage() { return _t0_storage; }
Remainder_type& get_remainder_storage() { return _remainder_storage; }
template< unsigned int Idx>
SExprGetter< SExpr , Idx > getChild()
{
SExprGetter< SExpr, Idx > getter(*this);
return getter;
}
static constexpr unsigned int childs()
{
return sizeof...(Subexprs) + 1;
}
};
template< typename T0>
class SExpr< T0 >
{
T0 _t0_storage;
public:
typedef T0 Expr_0_type;
typedef void Remainder_type;
SExpr(T0 _t) : _t0_storage(_t) {}
SExpr(T0&& _t) : _t0_storage(_t) {}
T0& get_storage() { return _t0_storage; }
static constexpr unsigned int childs()
{
return 1;
}
template< unsigned int Idx>
SExprGetter< SExpr , Idx > getChild()
{
SExprGetter< SExpr, Idx > getter(*this);
return getter;
}
};
template <typename... Exprs>
SExpr<Exprs...> _S_expr(Exprs... exprs) {
return
{
exprs...
};
};
#endif /* S_EXPRESSION_H */test.cpp
#include <iostream>
#include "sexpr.h"
#include <string>
using namespace std;
int main()
{
auto s_expr_1 = _S_expr(3);
auto s_expr_2 = _S_expr(3, std::string("foo"));
auto s_expr_3 = _S_expr(3, _S_expr(3, "bar"), std::string("foo"));
auto ff_1 = s_expr_1.getChild<0>().getValue();
cout << " ff_1: " << ff_1 << endl;
auto ff_2 = s_expr_2.getChild<1>().getValue();
cout << " ff_2: " << ff_2 << endl;
auto ff_3 = s_expr_3.getChild<1>().getChild<1>().getValue();
cout << " ff_3: " << ff_3 << endl;
cout << " s expr 3 has " << s_expr_3.childs() << " and the first leaf has " << s_expr_3.getChild< s_expr_3.childs() - 2 >().childs() << endl;
};https://stackoverflow.com/questions/10055979
复制相似问题