creating different 'int's

Started by
4 comments, last by Dreamforger 20 years, 5 months ago
I would like to use the same type, unsinged int, for two different things. Is there way to make the compiler complain when the usages are being mixed? My situation is as follows: I am devising a simple user interface for text-consoles. The interface returns handles for output fields, as well as for eventHandlers. I don''t need anything but a simple integer to identify those handles but I''d prefer that a handle returned for an output field can''t be used in the context of event handling. What I tried:
typedef unsigned int UIhandle;
typedef unsigned int UIevent;
doesn''t yield the desired incompatibility between UIhandle and UIevent Is there any way to achieve that? Maybe along the lines of anynomous structs, or something like it. --------------------------- I may be getting older, but I refuse to grow up
I may be getting older, but I refuse to grow up
Advertisement
typedef just makes an alias.. hence internally, they are the same type. If any function could only want a specific one.. then make them into structs, and require that specific type. If you are in a situation where you could need one, or other, or both to be accepted, then inherit them both from a common base (UIBase or something)... then if you want to take either, have a base type as a parameter... if you want a specific one... require one of these two derived types.
You could have different enums; they''ll map to int anyway but the compiler will yell for sure. Just specify the default (zero) element and make sure you typecast in the implementation to turn off compiler warnings. If you need the implementation to distinguish the two at runtime (not just compiler warnings), you could use the upper 8 or 16 bits to plug some sort of unique identifier; they are easily masked out. Similarly, you don''t need to start indexing at 0; the 0th element could start at index 0xDEADBEEFL so every operation would have to subtract out the per-type offset and check for boundaries.
I found this a time ago, I''m posting the whole thing.
Hello,It seems that every once in a while, someone mentions thatC++ is missing a "strong typedef" facility.This briefly-tested macro/template combination emulatesa simplified version of such a facility.  Maybe some ofyou will find it interesting to play with.I only tested it on an older compiler (g++ 2.96) sohopefully it doesn''t implode on the newer ones.The funny thing is, after I played around with strongtypedefs for a while, they didn''t seem as wonderfulas I originally thought they would be.  Maybe that''swhy C++ didn''t have them in the first place!USAGE:To create strong typedefs of "float" named"velocity_t" and "distance_t", you would call  STRONG_TYPEDEF(float, velocity_t);  STRONG_TYPEDEF(float, distance_t);The types "velocity_t" and "distance_t" will behave mostlylike floats, and will be initializable from floats, butwill not be interchangable. For example, the followingcode will be legal:  distance_t a=10;  distance_t b=20;  a += b;But the following code will not:  distance_t a=10;  velocity_t b=20;  a += b;To convert between the two, you have to access the .value memberlike so:  distance_t a=10;  velocity_t b=20;  a += b.value;Derek Ross==== Source File ===============================/*Notes about the STRONG_TYPEDEF macro.Usage:  STRONG_TYPEDEF(original_type, name_of_typedef);Example:  STRONG_TYPEDEF(double, dollars_t);STRONG_TYPEDEF creates a template type that is basicallya wrapper around a built-in type such as int or double.Most of the operators are overloaded to operate on thewrapped variable.Casting to the original type is not automatic.To get to the wrapped variable, access the ".value"member.STRONG_TYPEDEF cannot be used to define a typedefwithin a function, only globally.This was tested with g++ 2.96.*/#include <iostream>#include <utility>#include <vector>#include <algorithm>#include <string>#include <cmath>#define MAKE_STRONG_TYPEDEF_OP_CONST(rettype, op)\     rettype operator op \     (const strong_typedef_class<T,Unique_T>& r) \     const\     {\         return rettype(value op r.value);\     }\     rettype operator op (const T& r) const\     {\         return rettype(value op r);\     }#define MAKE_STRONG_TYPEDEF_OP_ASSIGN(op)\     strong_typedef_class<T,Unique_T>& operator op \     (const strong_typedef_class<T,Unique_T>& r) \     {\         value op r.value;\         return *this;\     }\     strong_typedef_class<T,Unique_T>& operator op \     (const T& r) \     {\         value op r;\         return *this;\     }#define MAKE_STRONG_TYPEDEF_UNOP(op)\     T operator op () const\     {\         return op value;\     }template< class T, class Unique_T>struct strong_typedef_class {     typedef T value_type;     typedef strong_typedef_class<T,Unique_T> self_type;     T value;     strong_typedef_class()     :value(T())     {}     strong_typedef_class(const T& v)     :value(v)     {}     strong_typedef_class(const strong_typedef_class& v)     :value(v.value)     {}     strong_typedef_class& operator=(const T&v)     {         value=T(v);         return *this;     }     strong_typedef_class& operator=(const strong_typedef_class& v)     {         value=T(v.value);         return *this;     }     /*     operator T&()     {         return value;     }     */     MAKE_STRONG_TYPEDEF_OP_CONST(bool, > )     MAKE_STRONG_TYPEDEF_OP_CONST(bool, < )     MAKE_STRONG_TYPEDEF_OP_CONST(bool, >= )     MAKE_STRONG_TYPEDEF_OP_CONST(bool, <= )     MAKE_STRONG_TYPEDEF_OP_CONST(bool, == )     MAKE_STRONG_TYPEDEF_OP_CONST(bool, != )     MAKE_STRONG_TYPEDEF_OP_CONST(bool, && )     MAKE_STRONG_TYPEDEF_OP_CONST(bool, || )     MAKE_STRONG_TYPEDEF_OP_CONST(self_type, +)     MAKE_STRONG_TYPEDEF_OP_CONST(self_type, -)     MAKE_STRONG_TYPEDEF_OP_CONST(self_type, /)     MAKE_STRONG_TYPEDEF_OP_CONST(self_type, *)     MAKE_STRONG_TYPEDEF_OP_CONST(self_type, %)     MAKE_STRONG_TYPEDEF_OP_CONST(self_type, <<)     MAKE_STRONG_TYPEDEF_OP_CONST(self_type, >>)     MAKE_STRONG_TYPEDEF_OP_CONST(self_type, &)     MAKE_STRONG_TYPEDEF_OP_CONST(self_type, |)     MAKE_STRONG_TYPEDEF_OP_CONST(self_type, ^)     MAKE_STRONG_TYPEDEF_OP_ASSIGN( += )     MAKE_STRONG_TYPEDEF_OP_ASSIGN( -= )     MAKE_STRONG_TYPEDEF_OP_ASSIGN( *= )     MAKE_STRONG_TYPEDEF_OP_ASSIGN( /= )     MAKE_STRONG_TYPEDEF_OP_ASSIGN( >>= )     MAKE_STRONG_TYPEDEF_OP_ASSIGN( <<= )     MAKE_STRONG_TYPEDEF_OP_ASSIGN( ^= )     MAKE_STRONG_TYPEDEF_OP_ASSIGN( &= )     MAKE_STRONG_TYPEDEF_OP_ASSIGN( |= )     MAKE_STRONG_TYPEDEF_OP_ASSIGN( %= )     MAKE_STRONG_TYPEDEF_UNOP(+)     MAKE_STRONG_TYPEDEF_UNOP(-)     MAKE_STRONG_TYPEDEF_UNOP(~)     MAKE_STRONG_TYPEDEF_UNOP(!)     strong_typedef_class<T,Unique_T>& operator ++ ()     {         ++value;         return *this;     }     strong_typedef_class<T,Unique_T>& operator -- ()     {         --value;         return *this;     }     strong_typedef_class<T,Unique_T>& operator ++ (int)     {         ++value;         return *this;     }     strong_typedef_class<T,Unique_T>& operator -- (int)     {         --value;         return *this;     }};template<class T, class Unique_T>std::ostream& operator<<(std::ostream& os, const strong_typedef_class<T,Unique_T>& r){     os << r.value;     return os;}template<class T, class Unique_T>std::istream& operator>>(std::istream& is, strong_typedef_class<T,Unique_T>& r){     is >> r.value;     return is;}#define STRONG_TYPEDEF(base_type, typedef_name)\     struct uniq_clas_for_strng_typdf__ ## typedef_name {};\     typedef strong_typedef_class<base_type,  \     uniq_clas_for_strng_typdf__ ## typedef_name > \     typedef_name;/////////////////// EXAMPLE /////////////////////STRONG_TYPEDEF(double, volts_st);STRONG_TYPEDEF(double, amps_st);STRONG_TYPEDEF(double, ohms_st);STRONG_TYPEDEF(double, watts_st);watts_st GetWatts(volts_st v, amps_st a){     return v.value * a.value;}watts_st GetWatts(amps_st a, ohms_st o){     return a.value * a.value * o.value;}watts_st GetWatts(volts_st v, ohms_st o){     return v.value * v.value / o.value;}#define PRINT(var) {std::cout<<#var<<": "<<var<<std::endl;}int main(){     volts_st v = 12.0;     amps_st  a = 5.99;     ohms_st  o = 2.01;     PRINT( v );     PRINT( a );     PRINT( o );     PRINT( GetWatts(v,a) );     PRINT( GetWatts(a,o) );     PRINT( GetWatts(v,o) );     // have to access ".value"     // to convert to double.     PRINT( sqrt(v.value) );     // next lines should give compiler errors:     // std::cout << GetWatts(o,v) << std::endl;     // v = a;}


[How To Ask Questions|STL Programmer''s Guide|Bjarne FAQ|C++ FAQ Lite|C++ Reference|MSDN]
Arguing on the internet is like running in the Special Olympics: Even if you win, you're still retarded.[How To Ask Questions|STL Programmer's Guide|Bjarne FAQ|C++ FAQ Lite|C++ Reference|MSDN]
typedef will not conflict...if you are using C++ you may use typedef in your class def and make them visible inside.

class MyClass{public:typedef unsigned int MYTYPE;};you can access MYTYPE by ::   MyClass::MYTYPE myvariable = 0;or typedef it again in another class   class SecondClass{public:typedef MyClass::MYTYPE  MYTYPE;};


and so on.

You can also use the 'unknown' namespace directive (it works in C too).






[edited by - blizzard999 on November 6, 2003 6:50:01 PM]
I just want to point out that in the code dalleboy posted, the post increment/decrement operators do not appear to be correctly defined, so you might want to proofread the rest of it to make sure its all correct.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk

This topic is closed to new replies.

Advertisement