为什么未正确推导出boost :: fusion序列中的struct array成员类型?

时间:2014-08-02 21:04:16

标签: c++ boost boost-fusion

我有以下示例代码:

#include <iostream>
#include <typeinfo>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/algorithm.hpp>

namespace MySpace
{
  struct TwoMembers
  {
    int intMember;
    char charMember[3];
  };
}

BOOST_FUSION_ADAPT_STRUCT(
  MySpace::TwoMembers,
  (int, intMember)
  (char, charMember[3])
)

struct FusionMemberPrinter
{
  FusionMemberPrinter() {}

  template <typename U>
  void operator()(U& data) const {
    std::cout << typeid(U).name() << " " << sizeof(U) << std::endl;
  }
};

int main(int argc, char** argv) {
  MySpace::TwoMembers data;
  boost::fusion::for_each(data, FusionMemberPrinter());
  return 0;
}

至少在VS 2013 Update 2中,此代码输出:

int 4
char 1

为什么charMember的类型不是推导为char [3]而是char? operator()将参数作为U&amp;,因此我的期望是将其推导为char [3]。

我的错误在哪里,顺便说一下。我有什么需要改变那个char [3]被推断出来的?

非常感谢提前!

2 个答案:

答案 0 :(得分:1)

宏BOOST_FUSION_ADAPT_STRUCT采用由(member_type, member_name)组成的一系列元组。因此,对于您的数组,它实际上被指定为类型为(char, charMember[3])的char。由于结果不正确,这实际上编译的机率很高:

 //! Here's a snippet of the expanded macro:
 template< >
 struct access::struct_member< MySpace::TwoMembers, 1 >
 {
     //! Note the type is defined as char.
     typedef char attribute_type;
     typedef attribute_type type;
     template<typename Seq> 
     struct apply
     {
          //[...] 
          //! Note that the method to return the sequence member actually returns 
          //! a char 1 index past the end of the array.
          static type call(Seq& seq) { return seq.charMember[3]; }
     };
 };

相反,您可以尝试使用boost::array<char, 3>代替。

#include <boost/array.hpp>

typedef boost::array<char, 3> char_array_3;
namespace MySpace
{
    struct TwoMembers
    {
        int intMember;
        char carray[3];
        char_array_3 charMember;
    };
}
BOOST_FUSION_ADAPT_STRUCT(
    MySpace::TwoMembers,
    (int, intMember)
    (char_array_3, charMember)
    )

答案 1 :(得分:1)

我迄今为止找到的一个解决方案是:

using char3 = char[3];
namespace MySpace
{
  struct TwoMembers
  {
    int intMember;
    char3 charMember;
  };
}

当然这只适用于C ++ 11。