1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
|
#include <iostream>
#include <stdexcept>
template < typename T > struct int_or_ptr
{
enum item_type { INT, PTR };
struct type_error : virtual std::domain_error { type_error() : std::domain_error( "type error" ) {} };
int_or_ptr( int i = 0 ) : tag(INT), int_val(i) {}
int_or_ptr( T* p ) : tag(PTR), ptr_val(p) {}
item_type type() const { return tag ; }
operator int& () { if( tag != INT ) throw type_error() ; return int_val ; }
operator const int& () const { if( tag != INT ) throw type_error() ; return int_val ; }
operator T*& () { if( tag != PTR ) throw type_error() ; return ptr_val ; }
operator T* const& () const { if( tag != PTR ) throw type_error() ; return ptr_val ; }
private:
item_type tag ;
union
{
int int_val ;
T* ptr_val ;
};
friend std::ostream& operator<< ( std::ostream& stm, int_or_ptr ip )
{ return ip.tag == INT ? stm << ip.int_val : stm << ip.ptr_val ; }
};
int main()
{
int a[] = { 1, 23, 456, 7890 } ;
int_or_ptr<int> mixed[] = { a[0], a+0, a[1], a+1, a[2], a+2, a[3], a+3 } ;
for( auto& ip : mixed ) std::cout << ip << ' ' ;
std::cout << '\n' ;
int value = mixed[4] ;
int* pointer = mixed[5] ;
mixed[4] = mixed[5] ;
// etc
}
|