Re: How to differentiate template classes.
Hi group,
Thank you for your answers - helpful as always. This reply is to all of
you even if directed to Daniel.
I should perhaps add a little background to my code. It is part of a library
that supports streaming of ASN.1 data. Peru is thus not a country - it stands
for Packed Encoding Rule Unaligned. ;-)
The generic name "my_template" could e.g. be a description of an ASN.1
SEQUENCE type - similar to a C++ std::tuple composed of ASN.1 types.
Den torsdag den 14. november 2013 22.48.58 UTC+1 skrev Daniel Kr?gler:
On 2013-11-13 19:47, peter koch larsen wrote:> Hi group,
Assume I have (the real code is more complex):
template< .... > class my_template;
typedef my_template<double,double> lat_long;
typedef my_template<double,double> complex;
I still have only one type, so I could input a complex to
a function expecting a complex - reducing typesafety.
What is perhaps worse, I can't overload on the two types.
std::ostream operator<< must be the same for both types.
One simple solution would be to simply inherit, but this
seems a little like abusing the system. E.g.:
struct complex: public my_template<double,double>
{
// very little boilerplate to construct
};
What does the group say about this? Should I worry?
I have not really grasped the reason for the current design choice, but
a simple way to make lat_long and complex different types can be
realized by adding a third template parameter to template my_template
that corresponds to a possible "type tag". Now you could define your
typedefs as follows:
struct lat_long_tag;
struct complex_tag;
typedef my_template<double,double, lat_long_tag> lat_long;
typedef my_template<double,double, complex_tag> complex;
I do not like to have the type-tag as part of the type-definition - it
clutters the interface, so I will use the "public" hack mentioned before.
This just gives me problems as I have a class of functions that operate on all my generic types - one of them of course being streaming. So for the sequence template class mentioned above, I would e.g. have a function:
template<typename... Fields>
bool stream_out(per_streamer&, asn1_sequence<Fields...> const& seq);
but this function would not be selected if I had the LatLon as a public
asn_sequence<double,double>.
So my idea is to instead have a templated selector in the line of:
template<typename T> struct asn_selector { typedef notype type;};
template<> struct asn_selector<double> { typedef doubletype type; };
template<typename... Fields>
template<> struct asn_selector<asn_sequence<Fields...>> {typedef sequencetype type; };
I have a small problem in that the last line does not compile (using MSVC
2013). I anyone has a hint to what is wrong I would appreciate an answer.
Best regards
Peter Koch
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]