10

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

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];
};

一致させようとしている文法は次のようになります。

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>));
}

特定のタイプに一致する文法を作成するにはどうすればよいですか?

編集:

proto::_およびproto::Nは、カスタムタイプでワイルドカードとして使用されていないようです。コードはこの文法でコンパイルされます(matchesアサーションはパスします):

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

ただし、ワイルドカードのいずれかが次のタイプの場合は機能しません。

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

または:

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

したがって、自分のタイプのワイルドカードを使用できない場合、式がベクトルを含む端末であるかどうかをテストするにはどうすればよいですか?

4

2 に答える 2

7

端末内のタイプをタイプと比較するには、タイプ特性を使用できます。指定されたタイプがベクトルの場合にtrueと評価されるいくつかの特性構造体を設定しています。

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_
{};

そして、これを文法に入れることができます。

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

私は以前にこのアプローチを試しましたが、それが機能しなかった理由は、特性構造体が含まれていたヘッダーの間違った名前空間で前方宣言されたvector<...>が原因でした。

于 2011-06-25T21:45:22.137 に答える
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<_, _> > 
    >));
}

お役に立てば幸いです。

于 2011-07-18T07:36:44.157 に答える