I have a legacy code:
template<Uint64 BuffLenT> Struct UNum : BasicTypes<BuffLenT>
{
typedef Uint64 NumberT;
inline NumberT operator() () const
{
NumberT ret = 0;
sscanf (this->buffer_, "%ul", &ret);
return ret;
}
};
Uint64 is a typedef and comes from "internal" headers. It may gets
defined to unsigned long or unsigned long long (depending upon
situations). Therefore to handle the situation I want to do the
following:
template<> Struct UNum<unsigned long long BuffLenT> :
BasicTypes<BuffLenT>
{
typedef Uint64 NumberT;
inline NumberT operator() () const
{
NumberT ret = 0;
sscanf (this->buffer_, "%ull", &ret);
return ret;
}
};
But this results in an compilation error. Any help in this regard will
be much appreciated.
Thanks in advance
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
If the format string is all that you need to vary with the type, then
factor it out:
template <typename T> char const * formatString();
template<> char const * formatString<unsigned long>() { return
"%ul"; }
template<> char const * formatString<unsigned long long>() { return
"%ull"; }
// ... other types omitted
Then, to use it:
sscanf (this->buffer_, formatString<NumberT>(), &ret);
If you don't mind passing unused values, you could even get rid of
the templates and just use traditional function overloading:
char const * formatString(unsigned long) { return "%ul"; }
char const * formatString(unsigned long long) { return "%ull"; }
// ... other types omitted
sscanf (this->buffer_, formatString(ret), &ret);
Hope this helps.
Chris
I suggest you do something like this.
// Primary template, everything else falls into here
template <typename> struct UNum;
// Specialization for unsigned long
template <> struct UNum <unsigned long> : BasicTypes<unsigned long>
{
typedef unsigned long NumberT;
inline NumberT operator() () const
{
// Special process for unsigned long
}
};
// Specialization for unsigned long long
template <> struct UNum <unsigned long long> : BasicTypes<unsigned
long long>
{
typedef unsigned long long NumberT;
inline NumberT operator() () const
{
// Special process for unsigned long long
}
};
If you design it this way, you will get what you want for unsigned
long and unsigned long long. The primary template is intentionally
left invalid so that everything else falls into it and generates
compiler errors which will surely catch your attention. Therefore, you
will never have a struct UNum <float> goes unnoticed which might what
you want or do not want. In case you want general cases are addressed
in a third way, you can give definition for the primary template.
> Uint64 is a typedef and comes from "internal" headers. It may gets
> defined to unsigned long or unsigned long long (depending upon
> situations).
What does Uint64 name in the compiler run that produces the error you
mention?
> But this results in an compilation error.
Please copy&paste the error message(s).
BuffLenT isn't a type, it's a value, so theres no intermediate
information there about it's type
actually all there needs to be is
template<class T>
struct meta_str;
template<>
struct meta_str<unsigned long>
{
static const char* str = "%ul"
};
template<>
struct meta_str<unsigned long long>
{
static const char* str = "%ull";
};
template<Uint64 BuffLenT> Struct UNum : BasicTypes<BuffLenT>
{
typedef Uint64 NumberT;
inline NumberT operator() () const
{
NumberT ret = 0;
sscanf (this->buffer_, meta_str<Uint64>::str, &ret);
return ret;
}
};