2

非プロト クラスのインスタンスをすべての目的でプロト ターミナルとして使用したいと考えています。この機能を有効にするために、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
}
4

1 に答える 1

1

回避策はありません。

C++ 言語では、一部の演算子に制限があります。特に、インデックス (operator[])、割り当て、および関数呼び出しの演算子は、非静的メンバー関数として定義する必要があります。

これは、 type の式の「左側」オペランドに暗黙的な変換が存在しないことを意味しlhs[rhs]ます。話の終わり。

私が知っているすべての EDSL フレームワークには、「リテラル」式をドメイン式として装飾するヘルパー関数がありboost::phoenix::val(x)ますboost::spirit::x3::as_parser(x)

于 2016-06-01T10:42:17.340 に答える