C++ 使用boost::proto构建s表达式

C++ 使用boost::proto构建s表达式,c++,c++11,s-expression,boost-proto,C++,C++11,S Expression,Boost Proto,我正在尝试使用以下终端使用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_ter

我正在尝试使用以下终端使用
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;
然而,这并不适合我

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
Test.cpp:18:33:错误:调用“boost::proto::exprns\uz::expr::expr(const char[4])没有匹配的函数
boost_1_46_0/boost/proto/proto_fwd.hpp:300:16:注意:候选项为:boost::proto::exprns_216;::expr::expr()
boost_1_46_0/boost/proto/proto_fwd.hpp:300:16:注意:boost::proto::exprns_uu::expr::expr(常量boost::proto::exprns_u::expr&)
测试cpp:18:33:错误:无法从“”推断“自动”
Test.cpp:18:73:错误:在“(”标记)之前应为“)”

我做错了什么?有没有建议如何使用
boost::proto
获得类似于或等效于s表达式的东西?

我怀疑您使用它的方式中存在一些固有的错误;我刚刚开始阅读,所以我完全是新手;不过,下面的编译并做了一些事情

#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;
}
(为将来的读者编写;
()
包含
{“foo”}
或可以删除的内容)。

类型
proto::expr
没有定义构造函数;因此,您的问题就来了。请尝试这样定义您的类型:

typedef proto::literalstring\u term\t;
typedef proto::literaluint32\u term\t;
typedef proto::literalfloat\u term\t;

我原来是在不依赖boost的情况下编写编译时S表达式的。唯一的问题是它依赖于c++11


sexpr.h
\ifndef S\u表达式
#定义S_表达式
#包括
模板类SExpr;
模板类SExprGetter;
模板
类sexpgetter
{
SExprType*树;
公众:
typedef typename SExprType::Expr_0_type返回_type;
SExprGetter(SExprType&_v):树(&_v){
sexpgetter(sexpgetter&&&o):树(_o.tree){}
return_type&getValue(){return tree->get_storage();}
模板
sexpgettergetChild()
{
返回getValue()。模板getChild();
}
静态constexpr unsigned int childs()
{
返回类型::childs();
}
};
模板
类sexpgetter
{
SExprType*树;
typedef typename SExprType::余数\类型余数\类型1;
公众:
typedef typename余数_type_1::Expr_0_type返回_type;
SExprGetter(SExprType&_v):树(&_v){
sexpgetter(sexpgetter&&&o):树(_o.tree){}
return_type&getValue(){return tree->get_restinum_storage().get_storage()}
模板
sexpgettergetChild()
{
返回getValue()。模板getChild();
}
静态constexpr unsigned int childs()
{
返回类型::childs();
}
};
模板
类sexpgetter
{
SExprType*树;
typedef typename SExprType::余数\类型余数\类型1;
typedef typename余数\类型\ 1::余数\类型余数\类型\ 2;
公众:
typedef typename余数_type_2::Expr_0_type返回_type;
SExprGetter(SExprType&_v):树(&_v){
sexpgetter(sexpgetter&&&o):树(_o.tree){}
return_type&getValue(){return tree->get_rements_storage().get_rements_storage().get_storage()}
模板
sexpgettergetChild()
{
返回getValue()。模板getChild();
}
静态constexpr unsigned int childs()
{
返回类型::childs();
}
};
模板
类sexpgetter
{
SExprType*树;
typedef typename SExprType::余数\类型余数\类型1;
typedef typename余数\类型\ 1::余数\类型余数\类型\ 2;
typedef typename余数\类型\ 2::余数\类型余数\类型\ 3;
公众:
typedef typename余数_type_3::Expr_0_type返回_type;
SExprGetter(SExprType&_v):树(&_v){
sexpgetter(sexpgetter&&&o):树(_o.tree){}
return_type&getValue(){return tree->get_rements_storage().get_rements_storage().get_rements_storage().get_storage()}
模板
sexpgettergetChild()
{
返回getValue()。模板getChild();
}
静态constexpr unsigned int childs()
{
返回类型::childs();
}
};
模板
类SExpr
{
T0_T0_存储;
SExpr\u余数\u存储;
公众:
typedef T0 Expr_0_类型;
typedef SExpr余数类型;
SExpr(T0_t,子表达式…sexprs):\ut0_存储(\u t),\u余数_存储(sexprs…{}
SExpr(T0&&&&t,子表达式和…SExpr):\u T0_存储(\u t),\u余数_存储(SExpr…{}
T0&get_storage(){return_T0_storage;}
余数存储类型&获取余数存储(){return\u resident\u storage;}
模板
sexpgettergetChild()
{
SExprGettergetter(*this);
回程吸气剂;
}
静态constexpr unsigned int childs()
{
返回大小为…(子表达式)+1;
}
};
模板
等级SExpr
{
T0_T0_存储;
公众:
typedef T0 Expr_0_类型;
typedef无效余数(u类型);
SExpr(T0_t):_T0_存储(_t){
SExpr(T0&&&t):存储({}
T0&get_storage(){return_T0_storage;}
静态constexpr unsigned int childs()
{
返回1;
}
模板
sexpgettergetChild()
{
SExprGettergetter(*this);
回程吸气剂;
}
};
模板
SExpr\u S\u expr(Exprs…Exprs){
返回
{
表达。。。
};
};
#endif/*S_表达式*/

test.cpp
#包括
#包括“sexpr.h”
#包括
使用名称空间std;
在里面
#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;
}
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);
}
#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 */
#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;
};