A Template that rejects classes.

  • Thread starter Dominic Connor, Pimp
  • Start date
D

Dominic Connor, Pimp

I've got a bit of code that shows which bits of a variable are 1 or 0
(OK, I'm making assumptions about 8 bit bytes and significance.)

But what I want to do is only allow this template to be instantiated
for base types, not classes.
I am averse to RTTI for this, but I keep thinking there's a bit of
syntactic sugar that will do it cleanly.
Solutions of the form "classes are bigger than 64 bits so reject them"
don't count :)

template <typename T> string DumpBits (T x)
{
unsigned int mask=1;
int i;
string s;

for ( i= 0; i != sizeof(x)*8; i++, mask *=2)
{
mask & x ? s = "1" + s : s = "0" + s;
}
return s;
}
 
V

Victor Bazarov

I've got a bit of code that shows which bits of a variable are 1 or 0
(OK, I'm making assumptions about 8 bit bytes and significance.)

But what I want to do is only allow this template to be instantiated
for base types, not classes.
I am averse to RTTI for this, but I keep thinking there's a bit of
syntactic sugar that will do it cleanly.
Solutions of the form "classes are bigger than 64 bits so reject them"
don't count :)

template <typename T> string DumpBits (T x)
{
unsigned int mask=1;
int i;
string s;

for ( i= 0; i != sizeof(x)*8; i++, mask *=2)
{
mask & x ? s = "1" + s : s = "0" + s;
}
return s;
}

Find a solution to recognize something as a class (SFINAE is used
along with "a pointer to member" syntax), and invert it. Look on the
web for "type is a class" template solution.

V
 
G

Gianni Mariani

I've got a bit of code that shows which bits of a variable are 1 or 0
(OK, I'm making assumptions about 8 bit bytes and significance.)

But what I want to do is only allow this template to be instantiated
for base types, not classes.
I am averse to RTTI for this, but I keep thinking there's a bit of
syntactic sugar that will do it cleanly.
Solutions of the form "classes are bigger than 64 bits so reject them"
don't count :)

template <typename T> string DumpBits (T x)
{
unsigned int mask=1;
int i;
string s;

for ( i= 0; i != sizeof(x)*8; i++, mask *=2)
{
mask & x ? s = "1" + s : s = "0" + s;
}
return s;
}

That code will not work for 64 bit types on many platforms.

You can list all the types you want it to work for by using specializations.
 
J

Jim Langston

Are you sure you don't really want
T mask = 1?
although I don't think that would work with enums, but what about when T is
larger than the size of unsigned int?

Not that it really matters, but would probably code this line like this:

s = (mask & x ? "1" : "0") + s;

Although I've had problems before trying to contcatenate to a string when
the first element is a char pointer. I guess operator= handles that.
That code will not work for 64 bit types on many platforms.

You can list all the types you want it to work for by using
specializations.

Why would this not work on some 64 bit implemenations? What is the
limitation that would prevent it from working? Is it the unsigned int?
 
G

Greg Herlihy

I've got a bit of code that shows which bits of a variable are 1 or 0
(OK, I'm making assumptions about 8 bit bytes and significance.)

But what I want to do is only allow this template to be instantiated
for base types, not classes.
I am averse to RTTI for this, but I keep thinking there's a bit of
syntactic sugar that will do it cleanly.
Solutions of the form "classes are bigger than 64 bits so reject them"
don't count :)

template <typename T> string DumpBits (T x)
{
unsigned int mask=1;
int i;
string s;

for ( i= 0; i != sizeof(x)*8; i++, mask *=2)
{
mask & x ? s = "1" + s : s = "0" + s;
}
return s;

}

I would recommend using the TR1 (or boost) type_traits class
templates; in particular, std::tr1::is_integral<> or
std::tr1::is_fundamental<> could be used to screen for suitable
template type arguments.

Greg
 
K

Kaz Kylheku

I've got a bit of code that shows which bits of a variable are 1 or 0
(OK, I'm making assumptions about 8 bit bytes and significance.)

But what I want to do is only allow this template to be instantiated
for base types, not classes.

Make the template function private to your module. Instead of exposing
the template function, expose a set of overloaded functions which use
the private function for their implementation.

template <typename T> void dump_bits_impl(T x) { /* ... */ }

int dump_bits(char x) { dump_bits_impl(x); }
int dump_bits(int x) { dump_bits_impl(x); }
int dump_bits(long x) { dump_bits_impl(x); }

// .. etc: repeat for all supported basic types

In spite of the trivial repetition, you're still exploiting the
template as a considerable labor-saving device.
I am averse to RTTI for this, but I keep thinking there's a bit of
syntactic sugar that will do it cleanly.
Solutions of the form "classes are bigger than 64 bits so reject them"
don't count :)

They aren't. How big is class empty {}; on your compiler? :)
 
J

James Kanze

I've got a bit of code that shows which bits of a variable are 1 or 0
(OK, I'm making assumptions about 8 bit bytes and significance.)
But what I want to do is only allow this template to be instantiated
for base types, not classes.
I am averse to RTTI for this, but I keep thinking there's a bit of
syntactic sugar that will do it cleanly.
Solutions of the form "classes are bigger than 64 bits so reject them"
don't count :)
template <typename T> string DumpBits (T x)
{
unsigned int mask=1;
int i;
string s;

for ( i= 0; i != sizeof(x)*8; i++, mask *=2)
{
mask & x ? s = "1" + s : s = "0" + s;
}
return s;

}

For starters, why not write the function something like:

template< typename T >
std::string
dumpBits( T value )
{
std::string result ;
while ( result.size() < sizeof( T ) * CHAR_BIT ) {
result += (value & 1 == 0) ? '0' : '1' ;
// or: result += (value & 1) + '0' ;
value >>= 1 ;
}
std::reverse( result.begin(), result.end() ) ;
return result ;
}

This will reject anything for which & or >> isn't defined, which
means anything that isn't either an integral type or designed to
behave like an integral type. Most likely, that's sufficient.
(Of course, the error message isn't very pretty. But then, is
it ever, when you use templates?)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,294
Messages
2,571,511
Members
48,218
Latest member
NatishaFin

Latest Threads

Top