We use middleware that generates types for us for various programming languages, including C ++. For the structures generated for C ++, I want to enter code that can be used for various data transformations, for example, output to std::ostream. Let them say that we have the following structure:
struct Foo {
int a;
double d;
};
Let's say I modify the middleware compiler to create the following template function:
template<typename Visitor>
void visit( Visitor &v, const Foo &data )
{
v.visit( "a", data.a );
v.visit( "d", data.d );
}
now I can use this code for different ways, and it should not affect anything if not used, for example make std::ostream::operator<<:
struct OstreamVisitor {
OstreamVisitor( std::ostream &os ) : m_os( os ) {}
void visit( const char *name, int i ) { m_os << name << "=" << i << std::endl; }
void visit( const char *name, double d ) { m_os << name << "=" << d << std::endl; }
std::ostream &m_os;
};
std::ostream &operator<<( std::ostream &out, const Foo &data )
{
OstreamVisitor v( out );
visit( v, data );
return out;
}
, , std::ostream &operator<< ,
template<typename T>
std::ostream &operator<<( std::ostream &os, const T &t );
, , . ? - , , .
. , . , - :
// system header
template<typename T>
struct visitable_tag;
// generated header
namespace FooNamespace {
struct Foo { ... };
template<>
struct visitable_tag<Foo> {};
}
// or maybe have tag in special namespace
namespace visitable_tag_namespace {
template<>
struct visitable_tag<FooNamespace::Foo> {};
}
. , , , , .