0

我正在尝试通过网络序列化数据,并且在大多数情况下,模板化正在得到回报。我在以下情况下遇到问题。

template < typename type >
class SerializedVector
{
public:
   bool  SerializeIn( const U8* data, int& bufferOffset );
   bool  SerializeOut( U8* data, int& bufferOffset ) const;

   vector< type > m_data;
};

在原始类型的情况下,序列化只是调用 memcpy(实际上是 htonl)的情况,但对于 std::string,我序列化字节数,然后 memcpy 后面的缓冲区。所以我有一个原始类型的模板函数和一个 std:string 的特化。很容易。

现在,我想支持在我的 m_data 成员中序列化自己的类......像这样:

struct TextEntry
{
   bool  SerializeIn( const U8* data, int& bufferOffset );
   bool  SerializeOut( U8* data, int& bufferOffset ) const;

   string   username;
   string   message;
};

class PacketTextHistoryResult : public BasePacket
{
public:
   PacketTextHistoryResult (){}

   bool  SerializeIn( const U8* data, int& bufferOffset );
   bool  SerializeOut( U8* data, int& bufferOffset ) const;

   SerializedVector< TextEntry > chat;
};

我已经尝试了很多东西,但这就是我卡住的地方......有更好的想法吗?这不起作用。

template <typename type>
struct calls_member_serialize : boost::false_type { };

template <> 
struct calls_member_serialize< std::string > : boost::false_type { };

template <typename type> 
struct calls_member_serialize< boost::is_class< type > > : boost::true_type { };

template < typename type >
bool  SerializedVector< type >::SerializeIn( const U8* data, int& bufferOffset )
{
   int num = m_data.size();
   Serialize::In( data, bufferOffset, num );

   struct localScope
   {
      static void do_work( const U8* data, int& bufferOffset, type temp, boost::true_type const & )
      {
         temp.SerializeIn( data, bufferOffset );  <<<<<<<< See how I invoke the self-serialization here.
      }
      static void do_work( const U8* data, int& bufferOffset, type temp, boost::false_type const & )
      {
         Serialize::In( data, bufferOffset, temp ); // call the standard template function
      }
   };

   for( int i=0; i<num; i++ )
   {
      type temp;
      localScope::do_work( data, bufferOffset, temp, ( calls_member_serialize< type >() ) ); //boost::is_fundamental<type>() || boost::is_class< std::string, type >()
      m_data.push_back( temp );
   }

   return true;
}
4

1 回答 1

1

我不认为你的第三个calls_member_serialize做你想让它做的事情。尝试这个:

template <typename type>
struct calls_member_serialize :  boost::is_class< type >  { };

template <> 
struct calls_member_serialize< std::string > : boost::false_type { };

那种方式calls_member_serialize<int>源自boost::false_typecalls_member_serialize<TextEntry>源自boost::true_type

您遇到的第二个问题是它struct localScope不是模板类,因此编译器将尝试为每种类型实例化 do_work 函数的两个版本,从而导致诸如std::string. 您还需要将 localScope 助手类设为模板。但是,模板类不能在函数范围内,所以它看起来像这样(未经测试):

namespace { // put in unnamed namespace to keep it local
   template<typename localType>
   struct localScope
   {
      static void do_work( const U8* data, int& bufferOffset, localType temp, boost::true_type const & )
      {
         temp.SerializeIn( data, bufferOffset );  
      }
      static void do_work( const U8* data, int& bufferOffset, localType temp, boost::false_type const & )
      {
         Serialize::In( data, bufferOffset, temp ); // call the standard template function
      }
   };
}

template < typename type >
bool  SerializedVector< type >::SerializeIn( const U8* data, int& bufferOffset )
{
   int num = m_data.size();
   Serialize::In( data, bufferOffset, num );

   for( int i=0; i<num; i++ )
   {
      type temp;
      localScope<type>::do_work( data, bufferOffset, temp, ( calls_member_serialize< type >() ) ); //boost::is_fundamental<type>() || boost::is_class< std::string, type >()
      m_data.push_back( temp );
   }

   return true;
}
于 2013-04-26T22:54:25.240 回答