Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Template: Specialization Help

2 views
Skip to first unread message

maverick

unread,
Dec 21, 2009, 9:54:29 AM12/21/09
to
Hi,

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! ]

Chris Uzdavinis

unread,
Dec 21, 2009, 7:19:29 PM12/21/09
to
On Dec 21, 8:54 am, maverick <mod...@gmail.com> wrote:
> 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.

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

萌 朱

unread,
Dec 21, 2009, 7:20:33 PM12/21/09
to
> [ Seehttp://www.gotw.ca/resources/clcm.htmfor info about ]

> [ comp.lang.c++.moderated. First time posters: Do this! ]

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.

Thomas Maeder

unread,
Dec 21, 2009, 7:25:15 PM12/21/09
to
maverick <mod...@gmail.com> writes:

> 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).

something_fit

unread,
Dec 22, 2009, 12:18:02 AM12/22/09
to
> [ Seehttp://www.gotw.ca/resources/clcm.htmfor info about ]

> [ comp.lang.c++.moderated. First time posters: Do this! ]

BuffLenT isn't a type, it's a value, so theres no intermediate
information there about it's type

something_fit

unread,
Dec 22, 2009, 12:24:14 AM12/22/09
to
On Dec 21, 2:54 pm, maverick <mod...@gmail.com> wrote:
> [ Seehttp://www.gotw.ca/resources/clcm.htmfor info about ]

> [ comp.lang.c++.moderated. First time posters: Do this! ]

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;
}

};

0 new messages