我正在尝试通过网络序列化数据,并且在大多数情况下,模板化正在取得成效。我遇到以下情况时遇到问题。
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;
}
答案 0 :(得分: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_type
来自calls_member_serialize<TextEntry>
,boost::true_type
来自struct localScope
。
您遇到的第二个问题是std::string
不是模板类,因此编译器将尝试为每种类型实例化do_work函数的两个版本,从而导致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;
}
等类型的编译器错误。您还需要将localScope帮助程序类作为模板。但是,模板类不能在函数范围内,因此它看起来像这样(未经测试):
{{1}}