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 回答