Предположительно имена и типы членов различаются в ваших структурах, в противном случае нет проблем.
И, вероятно, вам нужны ваши структуры, чтобы быть POD?
В этом случае разные структуры POD, главное ограничение в том, что шаблоны не могут обрабатывать обычные идентификаторы C ++ (что вы обязательно должны иметь для членов в структуре POD). Поэтому вам нужен макрос для определения operator<<
; только макросы могут обрабатывать идентификаторы. И тогда основная проблема заключается в том, как передать переменное число аргументов в макрос?
Ну, есть способы передать переменное число аргументов и перебрать их, используя поддержку макросов библиотеки Boost, но это сложно.
В любом случае вам придется указывать имена членов данных, поэтому будет не более чистым, чем код, который у вас уже есть .
Имея это в виду и воздерживаясь от соблазна использовать Boosted variadic macro, это может выглядеть так (я бы не стал использовать это, но если вам это нравится, вы можете также рассмотреть определение макроса для объявления заголовка функции) :
#include <iostream>
#include <string>
#define bswap_32( x ) x
#define bswap_16( x ) x
typedef unsigned uint32_t;
char const sep = '|';
template< class Type >
inline void write( Type const& v, std::ostream& stream )
{
stream << v;
}
template<>
inline void write( uint32_t const& v, std::ostream& stream )
{
stream << bswap_32( v );
}
template<>
inline void write( unsigned short const& v, std::ostream& stream )
{
stream << bswap_16( v );
}
template< class Type >
inline void write( char const legend[], Type const& v, std::ostream& stream )
{
stream << legend; write( v, stream ); stream << '|';
}
#define IMPLEMENT_OUTPUT_1( \
name1 \
) \
write( #name1 "=", r.name1, os );
#define IMPLEMENT_OUTPUT_2( \
name1, name2 \
) \
IMPLEMENT_OUTPUT_1( name1 ) \
write( #name2 "=", r.name2, os );
#define IMPLEMENT_OUTPUT_3( \
name1, name2, name3 \
) \
IMPLEMENT_OUTPUT_2( name1, name2 ) \
write( #name3 "=", r.name3, os );
#define IMPLEMENT_OUTPUT_4( \
name1, name2, name3, name4 \
) \
IMPLEMENT_OUTPUT_3( name1, name2, name3 ) \
write( #name4 "=", r.name4, os );
struct MyStruct
{
char c;
char s[10];
uint32_t i;
unsigned short us;
// friend std::ostream& operator<<( std::ostream& os, MyStruct const& r )
// {
// return os
// << "c=" << r.c << sep
// << "s=" << r.s << sep
// << "i=" << bswap_32( r.i ) << sep
// << "us=" << bswap_16( r.us ) << sep;
// }
friend std::ostream& operator<<( std::ostream& os, MyStruct const& r )
{
IMPLEMENT_OUTPUT_4( c, s, i, us )
return os;
}
};
int main()
{
using namespace std;
MyStruct const o = { 'A', "Bbbbbbb", 3, 4 };
cout << o << endl;
}
Опять же, я бы не стал использовать такую схему. Но, за исключением Boost'ing, он ближе всего подходит для различных структур POD. Так что, возможно, стоило бы увидеть это.
Привет и извините, что это, вероятно, не помогает,