将Boost.Proto语法与类型匹配

Matching a Boost.Proto grammar to a type

本文关键字:类型 语法 Boost Proto      更新时间:2023-10-16

我试图在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> >
{};

所以,如果我不能在自己的类型中使用通配符,我该如何测试表达式是否是包含向量的终端?

要将终端中的类型与类型进行比较,可以使用类型特征。我设置了一些特征结构,如果给定的类型是向量,则这些特征结构会评估为真:

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>()>
>

我以前尝试过这种方法,但它不起作用的原因是我转发了声明向量<…>在标头中错误的命名空间中,traits结构位于。

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

希望能有所帮助!