Reputation: 7905
I'm working on a class template that takes a single parameter T
of any type. For now I'm interested in integral types
; later on when I expand this class to use floating point types
I will then specialize this class.
Within this class I have a member variable that will store the max number of bit representations that can be stored in this type. For example:
Fundamental Types & Sizes: Range of values
signed char:
1Byte
,8 bits
,[-127,127]
for one's complement or [128,127]
for two's complement unsigned char:
1Byte
, 8 bits
, [0,255]
I can get the max value easier by using the unsigned version
of that type so in my template class (pseudo code here):
template<class T>
binaryRep {
T t_; // store the value
std::size_t size_ = sizeof( T ); // size in bytes
std::size_t maxVal = T( -1 ); // This is where I need T to be it's unsigned version.
};
If someone is to use this template class as such:
void someFunc() {
binaryRep<unsigned char> binUC; // This works fine
binaryRep<char> binSC; // Not giving the needed results.
}
Is there a way within the class's constructor to cast T
to unsigned T
?
In my constructor I was trying to do something like this:
binaryRep( const T& t ) : t_( static_cast<unsigned T>( t ) ) {
}
However this doesn't compile and didn't think it would either... but something of this nature is what I'm needing here.
[Note:] - The maxValue
member in this class represents the total number of viable binary bit combinations this type can store. For example: both char
& unsigned char
of a standard 8 bit
byte
has a max number of 256
binary bit combinations.
If you need more information than this please let me know.
Upvotes: 3
Views: 916
Reputation: 71
As far as I know, there is no STL
in C++ to give you an unsigned datatype
of the signed
version.
However, it isn't hard to write your own to get the unsigned
type of the corresponding signed
data type.
here is a sample of code I created for you.
template<typename T>
struct remove_signed { };
template<>
struct remove_signed<char> { typedef unsigned char Type; };
template<>
struct remove_signed<signed char> { typedef unsigned char Type; };
template<>
struct remove_signed<signed short int> { typedef unsigned short int Type; };
template<>
struct remove_signed<signed int> { typedef unsigned int Type; };
template<>
struct remove_signed<signed long int> { typedef unsigned long int Type; };
template<>
struct remove_signed<signed long long> { typedef unsigned long long Type; };
template<typename T>
using remove_signed_t = typename remove_signed<T>::Type;
int main(int argc, char** argv)
{
signed int x;
remove_signed<decltype(x)>::Type y; //y is unsigned int
signed char k;
remove_signed<decltype(k)>::Type l; //l is unsigned char
//or
remove_signed_t<decltype(k)> g; //g is unsigned char
return 0;
}
Good luck.
Edit: As @HolyBlackCat has mentioned, there is std::make_unsigned
which can give you unsigned
datatype of the signed
type
And it is exactly implemented as the code above, so if you want to know how std::make_unsigned
works, you can check the code.
Upvotes: 3
Reputation: 330
Setting maxVal
to size_ == sizeof(long long) ? (uLL) -1 : (1uLL << size_) - 1
should do the trick.
Upvotes: 0