ネットワーク全体でデータをシリアル化しようとしていますが、ほとんどの場合、テンプレート化は成果を上げています。次のシナリオに問題があります。
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 します。したがって、プリミティブ型のテンプレート関数が 1 つと、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;
}