#include <iostream>
using namespace std;

constexpr int n = 100;

template<typename T, T swapFor0> class SwappedValT
{
	T tVal;
public:
	SwappedValT() = default;
	
	SwappedValT(T t)
	{
		if     ( t == 0 )        { tVal = swapFor0; }
		else if( t == swapFor0 ) { tVal = 0; }
		else					 { tVal = t; } 
	}
	
	operator T()
	{ 
		if     ( tVal == 0 )        { return swapFor0; }
		else if( tVal == swapFor0 ) { return 0; }
		else                        { return tVal; } 
	}
};

SwappedValT<int, n> arr[5];

int main()
{
	 SwappedValT<int, n> t1{0}, t2{}, t3;
	 
	 cout << "zero init: " << t1 
			<< ", default init: " << t2 
			<< ", uninit: " << t3 
			<< endl;
	 
	 cout << "element of array with static storage duration = " << arr[2] << endl;
	 
	 // Note how SwappedValT<int, n> behaves just like int for all
	 // practical purposes. There are limits though with operations 
	 // on references
	 // like operator++() though which is not defined.
	 arr[2] = 3;
	 arr[3] = n;
	 arr[4] = 0;
	 
	 cout << "after assigning 3: " << arr[2] << endl;
	 cout << "after assigning swap val " << n << ": " << arr[3] << endl;
	 cout << "after assigning 0: " << arr[4] << endl;
	 cout << "arr elem containing 3 plus 4: " << (arr[2] + 4) << endl;
     return 0;
}