[C++] Traits and Template Specialization

Started by
0 comments, last by incin 13 years, 8 months ago
I am trying to create a number fo traits templates to package up
the following information:

* Type (a class or struct)
* Container
* A name for the collection

So far the following works ok:

extern char const NoneStr[] = "NONE";

template < typename T, typename CONT = void, const char* TagName = NoneStr >
struct MyTraits
{
typedef T ElementType;
typedef CONT ContainerType;
static const char* GetTag() { return TagName; }
};

This can then be specialised as follows:

extern char const StructOneStr[] = "StructOneName";

template<>
struct MyTraits<Struct1>
: MyTraits<SimpleOne, std::vector<StructOne>, StructOneStr > {};

extern char const StructTwoStr[] = "StructTwoName";

template<>
struct MyTraits<Struct2>
: MyTraits<SimpleTwo, std::deque<StructTwo>, StructTwoStr > {};

These traits can then be used in programs in the following way:
Note: this function uses boost serialization to write a collection to an xml file,
the Traits template is used to provide a nicer tag than the auto-generated one


template <typename T>
void SerializeToXmlFile( const MyTraits<T>::ContainerType& data,
const string& filename )
{
ofstream ofs(filename);
assert(ofs.good());
boost::archive::xml_oarchive oa(ofs);
oa & boost::serialization::make_nvp( MyTraits<T>::GetTag(), data);
}

For maps things are not write so straight forwards:

extern char const mapStr[] = "MapName";
typedef std::pair< string, long > MyMapData_t;

template<>
struct MyTraits<MyMapData_t> : MyTraits< MyMapData_t,
std::map< MyMapData_t::first_type,
MyMapData_t::second_type >,
MapStr > {};

Ideally I would like to find a way of writing a template such that
if T is of type std::pair the container is automatically set to a
map type. Unfortunately I have been unable to come up with the
correct syntax (is this possible using partial template specialization).



Advertisement
Try this:

template <typename T>
struct ConvPairToMap
{
typedef T in_type;
};
template <typename A, typename B>
struct ConvPairToMap<std::pair<A,B> >
{
typedef std::map<A,B> in_type;
};

ConvPairToMap<int>::in_type a = 5;
ConvPairToMap<std::pair<int,double> >::in_type b = std::map<int,double>();

This topic is closed to new replies.

Advertisement