I am trying to port the completely compile-time type-safe code, to the
use of this class:
// An example of completely type-safe code:
#include <iostream>
only double somefunc()
{
only double value= 1.0;
// Perform some operations
return value;
}
int main()
{
using namespace std;
only double result= somefunc();
only int x= static_cast<int>(result);
cout<< x<< endl;
only char c= 'a';
only signed char sc= 4HH;
only unsigned char uc= 4HHU;
only signed char schar= static_cast<signed char>(c);
}
Here is what I made so far:
#include <iostream>
template <class Value_type>
class only;
// It makes the object work with cout, provided the type Value_type is
// supported by cout.
template <class Value_type>
inline std:
stream & operator<<(std:
stream &objOstream, const
only<Value_type> &obj)
{
return objOstream<< obj.value();
}
template <class Value_type>
class only
{
Value_type m_value;
/* template<class U> only(U); // No constr. from other types.*/
public:
typedef Value_type value_type;
typedef Value_type& reference;
only(value_type value): m_value( value ) { }
value_type value() const { return m_value; }
// Makes casts, assignment and initialization to float/const float
to work
operator const float() const { return static_cast<const
float>(m_value); }
// Makes casts, assignment and initialization to double/const
double to work
operator const double() const { return static_cast<const
double>(m_value); }
// Makes casts, assignment and initialization to long double/const
long double to work
operator const long double() const { return static_cast<const long
double>(m_value); }
// Makes casts, assignment and initialization to char/const char to
work
operator const char() const { return static_cast<const
char>(m_value); }
// Makes casts, assignment and initialization to signed char/const
signed char to work
operator const signed char() const { return static_cast<const signed
char>(m_value); }
// Makes casts, assignment and initialization to unsigned char/const
unsigned char to work
operator const unsigned char() const { return static_cast<const
unsigned char>(m_value); }
// Makes casts, assignment and initialization to short/const short
to work
operator const short() const { return static_cast<const
short>(m_value); }
// Makes casts, assignment and initialization to unsigned
short/const unsigned short to work
operator const unsigned short() const { return static_cast<const
unsigned short>(m_value); }
// Makes casts, assignment and initialization to int/const int to work
operator const int() const { return static_cast<const int>(m_value); }
// Makes casts to unsigned/const unsigned to work
operator const unsigned() const { return static_cast<const
unsigned>(m_value); }
// Makes casts, assignment and initialization to long/const long to
work
operator const long() const { return static_cast<const
long>(m_value); }
// Makes casts, assignment and initialization to unsigned long/const
unsigned long to work
operator const unsigned long() const { return static_cast<const
unsigned long>(m_value); }
};
// An example of completely type-safe code:
#include <iostream>
only<double> somefunc()
{
only<double> value= 1.0;
// Perform some operations
return value;
}
int main()
{
using namespace std;
only<double> result= somefunc();
only<int> x= static_cast<int>(result);
cout<< x<< endl;
only<char> c= 'a';
only<signed char> sc= 4;
only<unsigned char> uc= 4;
only<signed char> schar= static_cast<signed char>(c);
}
I think this approach is promising, with the introduction of the new
prefixes:
"New prefixes for signed char, unsigned char, short, unsigned short
constants:
1. “HH” and “hh” for signed char constants.
2. “HHU” and “hhu” for unsigned char constants.
3. “H” and “h” for short constants.
4. “HU” and “hu” for unsigned short constants.
What do you think?