//Measurement.h
#pragma once
#include<iostream>
#include<string>
using namespace std;
struct meter
{
double value;
const string symtol = "m";
meter(double v)
:value(v)
{}
};
struct minute
{
double value;
string symtol = "min"
};
struct second
{
double value;
string symtol = "s";
second(double v)
:value(v)
{}
};
struct kilometer
{
double value;
string symtol = "km";
};
ostream& operator << (ostream& os, meter m)
{
os << m.value << m.symtol;
return os;
}
ostream& operator << (ostream& os, second s)
{
os << s.value << s.symtol;
return os;
}
template <typename T>
struct MeasurementTraits
{
typedef double UnitType;
static constexpr double scalar = 1;
};
template<>
struct MeasurementTraits<meter>
{
typedef meter UnitType;
static constexpr double scalar = 1;
};
template<>
struct MeasurementTraits<kilometer>
{
typedef meter UnitType;
static constexpr double scalar = 1000;
};
template<>
struct MeasurementTraits<second>
{
typedef second UnitType;
static constexpr double scalar = 1;
};
template<>
struct MeasurementTraits<minute>
{
typedef second UnitType;
static constexpr double scalar = 60;
};
template<typename T>
struct Measurement
{
double value;
typedef typename MeasurementTraits<T>::UnitType UnitType;
UnitType description()
{
return UnitType{ value *MeasurementTraits<T>::scalar };
}
Measurement(double v)
{
value = v;
}
};
//main.cpp
#include <iostream>
#include"Measurement.h"
using namespace std;
int main()
{
Measurement<meter> m1 = 20;
Measurement<kilometer> m2 = 11.2;
Measurement<second> m3 = 20;
Measurement<minute> m4 = 10;
Measurement<double> m5 = 10;
cout << m1.description() << endl;
cout << m2.description() << endl;
cout << m3.description() << endl;
cout << m4.description() << endl;
cout << m5.description() << endl;
system("pause");
return 0;
}