私はProtoを使って、幾何学的ベクトルを操作するDSELを構築しようとしています。割り当て式を受け取り、コンポーネントごとに展開する変換を作成しようとしています。たとえば、私は置き換えたい
p = q + r;
に
p[0] = q[0] + r[0],
p[1] = q[1] + r[1],
...,
p[N] = q[N] + r[N],
p;
これまでのところ、変換と組み合わせて、各ベクトルコンポーネントの式を再帰的に展開する変換テンプレートを作成することで、ほとんどの場合それを機能させることができました。unroll_vector_expr
distribute_subscript
boost::result_of
とで使用される「パラメータ」の論理的根拠が何であるか理解していないようですresult_of::make_expr
。ドキュメント、例、内部コードが混在しているようですExpr
、、。何をいつ使用すれば、実際の結果タイプと一致するのかわかりません。現在、エラーメッセージを調べ、との不一致を修正することで、エラーを試行して機能させました。ただし、式をディープコピーするとすぐに、ターミナルは参照によって保持されなくなり、コードが失敗します。impl::expr
impl::expr_param
result_type
const
&
struct distribute_subscript
: or_<
scalar_grammar
, when<
vector_literal
, _make_subscript( _, _state )
>
, plus< distribute_subscript, distribute_subscript >
, minus< distribute_subscript, distribute_subscript >
, multiplies< distribute_subscript, distribute_subscript >
, divides< distribute_subscript, distribute_subscript >
, assign< distribute_subscript, distribute_subscript >
>
{};
template< std::size_t I, std::size_t N >
struct unroll_vector_expr_c;
template< std::size_t I, std::size_t N >
struct unroll_vector_expr_c
: transform< unroll_vector_expr_c< I, N > >
{
template< typename Expr, typename State, typename Data >
struct impl
: transform_impl< Expr, State, Data >
{
typedef
typename result_of::make_expr<
tag::comma
, typename boost::result_of<
distribute_subscript(
Expr
, typename result_of::make_expr<
tag::terminal
, boost::mpl::size_t< I - 1 >
>::type
)
>::type
, typename boost::result_of<
unroll_vector_expr_c< I + 1, N >(
Expr
)
>::type
>::type
result_type;
result_type operator ()(
typename impl::expr_param expr
, typename impl::state_param state
, typename impl::data_param data
) const
{
return
make_expr< tag::comma >(
distribute_subscript()(
expr
, make_expr< tag::terminal >(
boost::mpl::size_t< I - 1 >()
)
)
, unroll_vector_expr_c< I + 1, N >() (
expr
)
);
}
};
};
template< std::size_t N >
struct unroll_vector_expr_c< N, N >
: transform< unroll_vector_expr_c< N, N > >
{
template< typename Expr, typename State, typename Data >
struct impl
: transform_impl< Expr, State, Data >
{
typedef
typename boost::result_of<
distribute_subscript(
Expr
, typename result_of::make_expr<
tag::terminal
, boost::mpl::size_t< N - 1 >
>::type
)
>::type
result_type;
result_type operator ()(
typename impl::expr_param expr
, typename impl::state_param state
, typename impl::data_param data
) const
{
return
distribute_subscript()(
expr
, make_expr< tag::terminal >(
boost::mpl::size_t< N - 1 >()
)
);
}
};
};
struct unroll_vector_expr
: transform< unroll_vector_expr >
{
template< typename Expr, typename State, typename Data >
struct impl
: transform_impl< Expr, State, Data >
{
typedef
typename dimension<
typename boost::remove_reference<
typename boost::result_of<
_value( State )
>::type
>::type
>::type
dimension;
typedef
typename result_of::make_expr<
tag::comma
, typename boost::result_of<
unroll_vector_expr_c< 1, dimension::value >(
Expr
)
>::type
, State
>::type
result_type;
result_type operator ()(
typename impl::expr_param expr
, typename impl::state_param state
, typename impl::data_param data
) const
{
return
make_expr< tag::comma >(
unroll_vector_expr_c< 1, dimension::value >()(
expr
)
, boost::ref( state )
);
}
};
};
からの結果とresult_type
一致し、値と参照の両方で保持されるように変換を作成するにはどうすればよいですか?operator ()
terminal
更新: Ericの回答後にコードが更新されました。result_type
との間で残っている唯一の不一致make_expr
は、の最初のインスタンス化に対するものですunroll_vector_expr_c
。ここで、は値ではなくconst参照terminal< mpl::size_t< 0 > >::type
によって保持されます。不思議なことに、同じテンプレートをより高いインデックスでインスタンス化しても、この問題は発生しません。
更新distribue_subscript
:変換を変更して添え字インデックスを値で強制的に取得した後、コードを完全に機能させることができました:
struct distribute_subscript
: or_<
scalar_grammar
, when<
vector_literal
, _make_subscript( _, _byval( _state ) ) // <-- HERE
>
, plus< distribute_subscript, distribute_subscript >
, minus< distribute_subscript, distribute_subscript >
, multiplies< distribute_subscript, distribute_subscript >
, divides< distribute_subscript, distribute_subscript >
, assign< distribute_subscript, distribute_subscript >
>
{};