2011-06-25 6 views
10

Boost.Protoでベクトル型と一致する文法を作ろうとしていますが、その型の端末に文法に合っていません。タイプ定義は次のようになります。マッチが失敗Boost.Proto文法を型にマッチする

namespace proto = boost::proto; 
using proto::_; 
using proto::N; 

struct test: 
    proto::terminal<vector<_, N> > 
{}; 

int main() 
{ 
    BOOST_MPL_ASSERT((proto::matches<proto::terminal<vector<float, 2> >::type, test>)); 
} 

私はどのように

template <typename T, unsigned D> 
struct vector 
{ 
    typedef T scalar; 
    enum { size = D }; 

    scalar& operator[](unsigned i) 
    { 
     return m_components[i]; 
    } 

    scalar const& operator[](unsigned i) const 
    { 
     return m_components[i]; 
    } 

private: 
    scalar m_components[size]; 
}; 

私が一致する取得しようとしている文法は次のようになります特定のタイプに一致する文法を作ってください。

EDIT:

それはそのプロト:: _表示され、プロト:: Nは、カスタムタイプではワイルドカードとして使用されていません。コードはこの文法(matches主張が通る)でコンパイルん:

struct test: 
    proto::terminal<vector<float, 2> > 
{}; 

しかし、ワイルドカードのいずれかをタイプしているときは動作しません:

struct test: 
    proto::terminal<vector<float, N> > 
{}; 

または:

struct test: 
    proto::terminal<vector<_, 2> > 
{}; 

自分の型をワイルドカードで表現できない場合、式がベクターを含むターミナルであるかどうかをテストするにはどうすればよいですか?

答えて

6

Boost.Protoは非型テンプレートパラメータでは機能しません。あなたができる場合は、次のように、一体型のラッパーを使用するように、ベクターの種類を変更します。

template <typename T, typename D> 
struct vector 
{ 
    typedef T scalar; 
    enum { size = D::value }; 

    scalar& operator[](unsigned i) 
    { 
     return m_components[i]; 
    } 

    scalar const& operator[](unsigned i) const 
    { 
     return m_components[i]; 
    } 

private: 
    scalar m_components[size]; 
}; 

次のように次に、あなたが一致することができるはずです。

int main() 
{ 
    BOOST_MPL_ASSERT((proto::matches< 
     proto::terminal<vector<float, mpl::int_<2> > >::type, 
     proto::terminal<vector<_, _> > 
    >)); 
} 

役に立てば幸い!

7

端末内のタイプをタイプと比較するには、タイプ特性を使用できます。

template <typename T> 
struct is_vector: 
    boost::mpl::false_ 
{}; 


template <typename T, unsigned Size> 
struct is_vector <dev::math::vector <T, Size> >: 
    boost::mpl::true_ 
{}; 

そして、あなたの文法でこれを置くことができます:私は指定されたタイプがベクトルの場合は、trueと評価されているいくつかの特徴を設定する構造体いる

proto::and_< 
    proto::terminal<_>, 
    proto::if_<is_vector<proto::_value>()> 
> 

私は前にこのアプローチを試してみましたしかし、それがうまくいかなかったのは、traft構造体があるヘッダの間違った名前空間にベクトル< ...があると宣言したからです。

+0

カスタムのマルチDアレイクラスで同じものを試そうとしています。 protoを私のクラスに、または私のクラスをprotoに適合させる方が良いかどうか分かります。私はすでに働いていることの多くを台無しにしたくないので、私は最初の道を辿ることを試みているが、私は確信していない – Giuliano