非原型对象作为终端
Non-proto objects as terminals
我想使用非原型 class 的实例作为原型终端
出于所有目的。要启用此功能,我使用 is_terminal
元函数并将其传递给 BOOST_PROTO_DEFINE_OPERATORS()
.
这实际上定义了运算符,所以下面的表达式使得
正如预期的那样,表达式树:
non_proto_obj * proto_obj; // creates proto expression tree
但是,我不能这样做:
non_proto_obj = proto_obj; // no operator=
non_proto_obj[proto_obj]; // no operator[]
而相反的编译:
proto_obj = non_proto_obj;
proto_obj[non_proto_obj];
看来我的对象不能转换为原型表达式。
这个问题有解决办法吗?
#include <iostream>
#include <boost/proto/proto.hpp>
#include <boost/mpl/int.hpp>
namespace mpl = boost::mpl;
namespace proto = boost::proto;
using proto::_;
template<typename Expr>
struct my_expression;
struct my_domain : proto::domain<proto::generator<my_expression> >
{};
template<int I> struct placeholder {};
template<typename Expr>
struct my_expression : proto::extends<Expr, my_expression<Expr>, my_domain>
{
explicit my_expression(Expr const &expr = Expr()) :
my_expression::proto_extends(expr)
{}
BOOST_PROTO_EXTENDS_USING_ASSIGN(my_expression<Expr>)
};
const my_expression<proto::terminal<placeholder<1>>::type> _1;
namespace app
{
struct non_proto_type
{};
template <typename T>
struct is_terminal : mpl::false_
{};
template<>
struct is_terminal<non_proto_type> : mpl::true_
{};
BOOST_PROTO_DEFINE_OPERATORS(is_terminal, my_domain)
non_proto_type non_proto;
}
int main()
{
_1 = app::non_proto; // ok, builds temporary proto expression
//app::non_proto = _1; // does not compile! no operator=
_1[app::non_proto]; // ok
//app::non_proto[_1]; // does not compile! no operator[]
(+app::non_proto)[_1]; // ok! applying unary + to make a proto expression first, then operator[] is available
}
没有解决方法。
C++语言对一些运算符进行了限制。值得注意的是,索引(operator[])、赋值和函数调用运算符必须定义为非静态成员函数。
这意味着 lhs[rhs]
类型的表达式中的 "left-hand-side" 操作数永远不会有隐式转换。故事结束。
我知道的所有 EDSL 框架都有辅助函数来将你的 "literal" 表达式修饰为域表达式,例如boost::phoenix::val(x)
或 boost::spirit::x3::as_parser(x)
.
我想使用非原型 class 的实例作为原型终端
出于所有目的。要启用此功能,我使用 is_terminal
元函数并将其传递给 BOOST_PROTO_DEFINE_OPERATORS()
.
这实际上定义了运算符,所以下面的表达式使得 正如预期的那样,表达式树:
non_proto_obj * proto_obj; // creates proto expression tree
但是,我不能这样做:
non_proto_obj = proto_obj; // no operator=
non_proto_obj[proto_obj]; // no operator[]
而相反的编译:
proto_obj = non_proto_obj;
proto_obj[non_proto_obj];
看来我的对象不能转换为原型表达式。 这个问题有解决办法吗?
#include <iostream>
#include <boost/proto/proto.hpp>
#include <boost/mpl/int.hpp>
namespace mpl = boost::mpl;
namespace proto = boost::proto;
using proto::_;
template<typename Expr>
struct my_expression;
struct my_domain : proto::domain<proto::generator<my_expression> >
{};
template<int I> struct placeholder {};
template<typename Expr>
struct my_expression : proto::extends<Expr, my_expression<Expr>, my_domain>
{
explicit my_expression(Expr const &expr = Expr()) :
my_expression::proto_extends(expr)
{}
BOOST_PROTO_EXTENDS_USING_ASSIGN(my_expression<Expr>)
};
const my_expression<proto::terminal<placeholder<1>>::type> _1;
namespace app
{
struct non_proto_type
{};
template <typename T>
struct is_terminal : mpl::false_
{};
template<>
struct is_terminal<non_proto_type> : mpl::true_
{};
BOOST_PROTO_DEFINE_OPERATORS(is_terminal, my_domain)
non_proto_type non_proto;
}
int main()
{
_1 = app::non_proto; // ok, builds temporary proto expression
//app::non_proto = _1; // does not compile! no operator=
_1[app::non_proto]; // ok
//app::non_proto[_1]; // does not compile! no operator[]
(+app::non_proto)[_1]; // ok! applying unary + to make a proto expression first, then operator[] is available
}
没有解决方法。
C++语言对一些运算符进行了限制。值得注意的是,索引(operator[])、赋值和函数调用运算符必须定义为非静态成员函数。
这意味着 lhs[rhs]
类型的表达式中的 "left-hand-side" 操作数永远不会有隐式转换。故事结束。
我知道的所有 EDSL 框架都有辅助函数来将你的 "literal" 表达式修饰为域表达式,例如boost::phoenix::val(x)
或 boost::spirit::x3::as_parser(x)
.