【问题标题】:Matching a Boost.Proto grammar to a type将 Boost.Proto 语法与类型匹配
【发布时间】:2011-09-22 17:29:31
【问题描述】:

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

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

【问题讨论】:

    标签: c++ boost expression-templates boost-proto


    【解决方案1】:

    要将终端中的类型与类型进行比较,您可以使用类型特征。如果给定类型是向量,我设置了一些特征结构,这些结构评估为 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<...>。

    【讨论】:

    • 只是在自定义多维数组类上尝试相同。想知道是让 proto 适应我的班级,还是让我的班级适应 proto 更好。我正在尝试遵循第一条路径,因为我不想弄乱很多已经工作的东西,但我不确定
    【解决方案2】:

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

    希望有帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-19
      • 2014-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多