PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.cplus > Upsigning or downsigning
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
Upsigning or downsigning

Réponse
 
LinkBack Outils de la discussion
Vieux 07/04/2008, 17h40   #1
Damian
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Upsigning or downsigning

Is there any way to manipulate a template parameter to change its
signedness?

For example,

template <typename T>
void foo(signed T a, unsigned T b) {

}

defines a templated function that is instantiated with a base numeric
type (e.g. int or long) but is referred by signed and unsigned
variants.

Also, how do I convert a typename to signed or unsigned? For example,
if I had some variable k I wanted to cast to the unsigned variant of
type T, I'd like to be able to do

j = (unsigned_type(T))k

but I'm not sure if it's possible to do something like that. Is there
anyway to "upsign" (i.e. convert a numeric type to signed) or
"downsign" (i.e. convert a numeric type to unsigned) similar to how
one might upcast or downcast a number?

Thanks!

Damian Eads
  Réponse avec citation
Vieux 07/04/2008, 18h29   #2
Fei Liu
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Upsigning or downsigning

Damian wrote:
> Is there any way to manipulate a template parameter to change its
> signedness?
>
> For example,
>
> template <typename T>
> void foo(signed T a, unsigned T b) {
>
> }
>
> defines a templated function that is instantiated with a base numeric
> type (e.g. int or long) but is referred by signed and unsigned
> variants.
>
> Also, how do I convert a typename to signed or unsigned? For example,
> if I had some variable k I wanted to cast to the unsigned variant of
> type T, I'd like to be able to do
>
> j = (unsigned_type(T))k
>
> but I'm not sure if it's possible to do something like that. Is there
> anyway to "upsign" (i.e. convert a numeric type to signed) or
> "downsign" (i.e. convert a numeric type to unsigned) similar to how
> one might upcast or downcast a number?
>
> Thanks!
>
> Damian Eads


Yes, because signed-ness is part of a function signature that function
overloading uses. You can devise a 'type-of' class template to determine
if a type is signed or unsigned at compile time.

Fei
  Réponse avec citation
Vieux 07/04/2008, 18h30   #3
Abhishek Padmanabh
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Upsigning or downsigning

On Apr 7, 9:40pm, Damian <damian.e...@gmail.com> wrote:
> Is there any way to manipulate a template parameter to change its
> signedness?
>
> For example,
>
> template <typename T>
> void foo(signed T a, unsigned T b) {
>
> }
>
> defines a templated function that is instantiated with a base numeric
> type (e.g. int or long) but is referred by signed and unsigned
> variants.


Would have, probably, worked if T worked like a macro replacement but
it does not.

>
> Also, how do I convert a typename to signed or unsigned? For example,
> if I had some variable k I wanted to cast to the unsigned variant of
> type T, I'd like to be able to do
>
> j = (unsigned_type(T))k
>
> but I'm not sure if it's possible to do something like that. Is there
> anyway to "upsign" (i.e. convert a numeric type to signed) or
> "downsign" (i.e. convert a numeric type to unsigned) similar to how
> one might upcast or downcast a number?


No that I know of, but there may be. I think what you are trying to do
is to force the template to work with unsigned types only. There could
be two ways in which you can accomplish that depending on what you are
actually trying to do.

1) Don't let the template instantiate if the type is a signed type
with something like this, if you want callers to not pass signed
types:

template<typename T>
void func(T t)
{
BOOST_STATIC_ASSERT(boost::is_signed<T>::value);
//rest of the code, T will be signed assuming T is a integral type
//might put an assert if not boost::is_integral or as required
}

2) Provide overloads for the signed types that redirect the call to
the template with static_cast or explicitly specifying instantiation
type to make the argument unsigned:

template<typename T>
void func(T t)
{
//rest code
}

void func(int i) { func<unsigned int>(i);}
void func(char c) { func<unsigned char>(c);}

  Réponse avec citation
Vieux 07/04/2008, 23h18   #4
tragomaskhalos
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Upsigning or downsigning

On 7 Apr, 17:40, Damian <damian.e...@gmail.com> wrote:
> Also, how do I convert a typename to signed or unsigned? For example,
> if I had some variable k I wanted to cast to the unsigned variant of
> type T, I'd like to be able to do
>
> j = (unsigned_type(T))k
>
> but I'm not sure if it's possible to do something like that. Is there
> anyway to "upsign" (i.e. convert a numeric type to signed) or
> "downsign" (i.e. convert a numeric type to unsigned) similar to how
> one might upcast or downcast a number?
>


How about this ?
<code>
template<typename T> struct sign_variants {};
#define MAKE_SVS_FOR(T) \
template<> struct sign_variants<T> {\
typedef T signed_t;\
typedef unsigned T unsigned_t;\
};\
template<> struct sign_variants<unsigned T> {\
typedef T signed_t;\
typedef unsigned T unsigned_t;\
};
MAKE_SVS_FOR(char)
// hmmm ... glossing over char vs signed char vs unsigned char ...
MAKE_SVS_FOR(int)
MAKE_SVS_FOR(long)
MAKE_SVS_FOR(short)
// add any other flavours your compiler supports

#undef MAKE_SVS_FOR

// then e.g.
#include <iostream>

const char* foo(long x)
{ return "slong"; }
const char* foo(unsigned long x)
{ return "ulong"; }

void signedness()
{
std::cout << foo(sign_variants<long>::signed_t()) << '\n';
std::cout << foo(sign_variants<long>::unsigned_t()) << '\n';
std::cout << foo(sign_variants<unsigned long>::signed_t()) << '\n';
std::cout << foo(sign_variants<unsigned long>::unsigned_t()) <<
'\n';
}
/*
output
slong
ulong
slong
ulong
*/
</code>

Obviously you'd use sign_variants inside a template.
  Réponse avec citation
Vieux 07/04/2008, 23h47   #5
Damian
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: Upsigning or downsigning

On Apr 7, 10:30 am, Abhishek Padmanabh <abhishek.padman...@gmail.com>
wrote:
> On Apr 7, 9:40 pm, Damian <damian.e...@gmail.com> wrote:
>
> > Is there any way to manipulate a template parameter to change its
> > signedness?

>
> > For example,

>
> > template <typename T>
> > void foo(signed T a, unsigned T b) {

>
> > }

>
> > defines a templated function that is instantiated with a base numeric
> > type (e.g. int or long) but is referred by signed and unsigned
> > variants.

>
> Would have, probably, worked if T worked like a macro replacement but
> it does not.
>
> > Also, how do I convert a typename to signed or unsigned? For example,
> > if I had some variable k I wanted to cast to the unsigned variant of
> > type T, I'd like to be able to do

>
> > j = (unsigned_type(T))k

>
> > but I'm not sure if it's possible to do something like that. Is there
> > anyway to "upsign" (i.e. convert a numeric type to signed) or
> > "downsign" (i.e. convert a numeric type to unsigned) similar to how
> > one might upcast or downcast a number?

>
> No that I know of, but there may be. I think what you are trying to do
> is to force the template to work with unsigned types only. There could
> be two ways in which you can accomplish that depending on what you are
> actually trying to do.
>
> 1) Don't let the template instantiate if the type is a signed type
> with something like this, if you want callers to not pass signed
> types:
>
> template<typename T>
> void func(T t)
> {
> BOOST_STATIC_ASSERT(boost::is_signed<T>::value);
> //rest of the code, T will be signed assuming T is a integral type
> //might put an assert if not boost::is_integral or as required
>
> }


Ah, so passing an unsigned type here generates an assertion. I see
that you address how to handle overloading with signed types below.

> 2) Provide overloads for the signed types that redirect the call to
> the template with static_cast or explicitly specifying instantiation
> type to make the argument unsigned:
>
> template<typename T>
> void func(T t)
> {
> //rest code
>
> }
>
> void func(int i) { func<unsigned int>(i);}
> void func(char c) { func<unsigned char>(c);}


Since I was asked by several people already for an example. I will
give one. Suppose you want to take the absolute value on a value of
any integer type. The absolute value of an unsigned would just leave
the value unchanged and the absolute value of a signed type would set
the signed bit to naught.
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 11h16.


Édité par : vBulletin® version 3.7.2
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,14853 seconds with 13 queries