Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Presumably member names and types are different in your structs, otherwise no problem.</p> <p>And presumably you need your structs to be POD?</p> <p>In that case, different POD structs, the main constraint is that templates can't handle ordinary C++ identifiers (which is what you necessarily have for the members in a POD struct). So you then need a macro to define the <code>operator&lt;&lt;</code>; only macros can handle identifiers. And then the main problem is, how to pass a variable number of arguments to the macro?</p> <p>Well, there are ways to pass variable number of arguments and iterate over them, using the Boost library's macro support, but that's complicated.</p> <p>You will have to provide the data member names anyway, and so <em>it will be not be more clean than the code that you already have</em>.</p> <p>Keeping that in mind, and refraining from the temptation to use Boosted variadic macros, it can look like this (I wouldn't use it, but if you like it you may consider also defining a macro for the function head declaration):</p> <pre><code>#include &lt;iostream&gt; #include &lt;string&gt; #define bswap_32( x ) x #define bswap_16( x ) x typedef unsigned uint32_t; char const sep = '|'; template&lt; class Type &gt; inline void write( Type const&amp; v, std::ostream&amp; stream ) { stream &lt;&lt; v; } template&lt;&gt; inline void write( uint32_t const&amp; v, std::ostream&amp; stream ) { stream &lt;&lt; bswap_32( v ); } template&lt;&gt; inline void write( unsigned short const&amp; v, std::ostream&amp; stream ) { stream &lt;&lt; bswap_16( v ); } template&lt; class Type &gt; inline void write( char const legend[], Type const&amp; v, std::ostream&amp; stream ) { stream &lt;&lt; legend; write( v, stream ); stream &lt;&lt; '|'; } #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&amp; operator&lt;&lt;( std::ostream&amp; os, MyStruct const&amp; r ) // { // return os // &lt;&lt; "c=" &lt;&lt; r.c &lt;&lt; sep // &lt;&lt; "s=" &lt;&lt; r.s &lt;&lt; sep // &lt;&lt; "i=" &lt;&lt; bswap_32( r.i ) &lt;&lt; sep // &lt;&lt; "us=" &lt;&lt; bswap_16( r.us ) &lt;&lt; sep; // } friend std::ostream&amp; operator&lt;&lt;( std::ostream&amp; os, MyStruct const&amp; r ) { IMPLEMENT_OUTPUT_4( c, s, i, us ) return os; } }; int main() { using namespace std; MyStruct const o = { 'A', "Bbbbbbb", 3, 4 }; cout &lt;&lt; o &lt;&lt; endl; } </code></pre> <p>Again, I would not use a scheme like this. But, except for Boost'ing, it's the closest you get for different POD structs. So I might be worth having seen it.</p> <p>Cheers &amp; sorry that this probably not helps,</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload