首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >BOOST_FUSION_ADAPT_TPL_STRUCT和模板数组大小

BOOST_FUSION_ADAPT_TPL_STRUCT和模板数组大小
EN

Stack Overflow用户
提问于 2013-04-12 09:55:18
回答 2查看 607关注 0票数 4

多亏了BOOST_FUSION_ADAPT_TPL_STRUCT,我正在尝试迭代一个C++模板结构。我的结构包含固定大小的多维数组,其大小是模板参数。如果我们考虑对Boost的示例进行修改以适应我的问题:

代码语言:javascript
复制
#include <iostream>
#include <string>
#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>

// Example:
// http://www.boost.org/doc/libs/1_53_0/libs/fusion/doc/html/fusion/adapted/adapt_tpl_struct.html

namespace demo
{
    template<typename T, unsigned int SIZE1, unsigned int SIZE2, typename Name, typename Age>
    struct employee
    {
        Name name;
        Age age;
        T ar[SIZE1][SIZE2];
    };
}

// Any instantiated demo::employee is now a Fusion sequence
BOOST_FUSION_ADAPT_TPL_STRUCT(
    (T)(SIZE1)(SIZE2)(Name)(Age),
    (demo::employee) (T)(SIZE1)(SIZE2)(Name)(Age),
    (Name, name)
    (Age, age)
    (T, ar[SIZE1][SIZE2]))

int main()
{
    demo::employee<float, 2, 2, std::string, int> e;
    e.name = "Bob";
    e.age = 25;
    e.ar[0][0] = e.ar[1][0] = 0.1;
    e.ar[0][1] = e.ar[1][1] = 0.2;
}

编译失败。此外,如果我们只添加一个整型模板参数,而不使用它作为数组大小,它也会失败。

使用BOOST_FUSION_ADAPT_TPL_STRUCT能做到这一点吗?如果不是,我该怎么做呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-04-12 10:06:23

来自doc

序列(template_param0)(template_param1)...声明使用的模板类型参数的名称。

而你有的非类型模板参数 SIZE

代码语言:javascript
复制
template<typename T, unsigned int SIZE, typename Name, typename Age>
struct employee

您可以将其转换为type模板参数,并使用boost::mpl::int_作为载体大小的包装。

现在,您的代码是。

代码语言:javascript
复制
template<int Size>
struct Array
{
    template<typename T>
    struct Of
    {
        typedef T type[Size];
    };
};

namespace demo
{
    template<typename T, typename SIZE, typename Name, typename Age>
    struct employee
    {
        Name name;
        Age age;
        T ar[SIZE::value];
    };
}

// Any instantiated demo::employee is now a Fusion sequence
BOOST_FUSION_ADAPT_TPL_STRUCT(
    (T)(SIZE)(Name)(Age),
    (demo::employee) (T)(SIZE)(Name)(Age),
    (Name, name)
    (Age, age)
    (typename Array<SIZE::value>::template Of<T>::type, ar))

 //...
 demo::employee<float, int_<2>, std::string, int> e;
票数 3
EN

Stack Overflow用户

发布于 2013-04-15 11:57:41

在与叶夫根尼·帕纳苏克进行了长时间的交谈后,我最终做了一些有点不同的事情。因为我希望能够对数据结构进行一些简单的算术运算,所以我决定使用Eigen::Map而不是Boost::multi_array,因为它提供了广泛的运算符以及清晰的文档。

因此,较高级别的循环由boost::fusion::for_each处理,较低级别的循环由本征处理。数组被线性地映射到特征向量。大小在data_eigen的构造函数中传递。

代码语言:javascript
复制
#include <iostream>

#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
#include <boost/fusion/include/for_each.hpp>
#include <boost/bind.hpp>

#include <Eigen/Core>

namespace demo
{
template<typename T, int SIZE1, int SIZE2>
struct data
{
    T ar1[SIZE1][SIZE2];
    T ar2[SIZE1][SIZE2];
};

template<typename T>
struct EigenMap
{
    typedef Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, 1> > type;
};

template<typename T>
struct data_eigen
{
    template <int SIZE1, int SIZE2>
    data_eigen(data<T,SIZE1,SIZE2>& src)
        : ar1(typename EigenMap<T>::type(&src.ar1[0][0], SIZE1*SIZE2)),
          ar2(typename EigenMap<T>::type(&src.ar2[0][0], SIZE1*SIZE2))
    {
    }

    typename EigenMap<T>::type ar1;
    typename EigenMap<T>::type ar2;
};


struct print
{
    template<typename T>
    void operator()(const Eigen::Map<Eigen::Matrix<T, Eigen::Dynamic, 1> >& t) const
    {
        std::cout << t.transpose() << std::endl;
    }
};

struct scalarMult
{
    template<typename T, typename U>
    void operator()(T& t, U& u) const
    {
        t *= u;
    }
};

}

BOOST_FUSION_ADAPT_TPL_STRUCT
(
    (T),
    (demo::data_eigen) (T),
    (typename demo::EigenMap<T>::type, ar1)
    (typename demo::EigenMap<T>::type, ar2)
)

int main()
{
    typedef float REALTYPE;
    const int SIZE1 = 2;
    const int SIZE2 = 2;

    // Basic data structure with multidimensional arrays
    demo::data<REALTYPE, SIZE1, SIZE2> d;
    for (unsigned int i = 0; i < SIZE1; ++i)
        for (unsigned int j = 0; j < SIZE2; ++j)
        {
            d.ar1[i][j] = (i+1)*(j+1);
            d.ar2[i][j] = i + j;
        }

    // Eigen::Map + BOOST_FUSION_ADAPT_TPL_STRUCT
    demo::data_eigen<REALTYPE> eig_d(d);

    std::cout << "d:" << std::endl;
    boost::fusion::for_each(eig_d, demo::print());
    std::cout << std::endl;

    boost::fusion::for_each(eig_d, boost::bind<void>(demo::scalarMult(), _1, 2.0));
    std::cout << "2 * d:" << std::endl;
    boost::fusion::for_each(eig_d, demo::print());
    std::cout << std::endl;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15961855

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档