User defined literals are literals for user defined types. After having the user defined types (class) and user defined operators (operator overloading), we now have user defined constants (literals) in C++11.
Ex: If cattle is the user defined type, 10_cows, 20_bulls etc can be user defined literals.
It wouldn't have been fair if integers had to be initialized only as decimal!!
User defined literals add more readability/ meaning to the user defined types by explicitly stating what the literals mean than leaving it to the programmer to assume or to investigate its usage to find out how the literals are actually used.
Programmers can use his/her choice of the units rather than having to convert the literals to the desired (an implementation detail) units manually. The programmer can be assured that the inputs to objects are treated as desired.
Improves maintainability since the units can be extended
Let us see an example to define and use them.
Run the above code here.
The same can be achieved without user defined literals too! for example, one class for each unit that gets the money in the desired unit. or with generic programming.
Is it really a deal breaker? I will leave that for you to decide! An interesting discussion on SO that answers possible questions is worth looking at.
Ex: If cattle is the user defined type, 10_cows, 20_bulls etc can be user defined literals.
It wouldn't have been fair if integers had to be initialized only as decimal!!
int X = 0XFF; // Nah! not possible int Y = 0888; // yeah, i got it right. Its a decimal 888 int Z = 0110; // Sadly, I'm still not upgraded to C++14 and i understand only decimal!!!
User defined literals add more readability/ meaning to the user defined types by explicitly stating what the literals mean than leaving it to the programmer to assume or to investigate its usage to find out how the literals are actually used.
cMoney m1(10); // Do you think I'm worth 10USD? I'm worth 10INR. Check out my implementation! cMoney m2(10.5_inr); // We both know what I'm worth of :)
Programmers can use his/her choice of the units rather than having to convert the literals to the desired (an implementation detail) units manually. The programmer can be assured that the inputs to objects are treated as desired.
cMoney m1(10); // I'm worth 10INR. If you don't think so, init my worth in INR!!
Improves maintainability since the units can be extended
cMoney m2(10.5_inr); cMoney m2(10.5_usd); oops, it should have been a different unit!
Let us see an example to define and use them.
class cMoney
{
private:
long double value; // always store in USD
// Accept money only in acceptable currencies.
// The acceptable currencies will be defined by the user defined literals.
cMoney(long double money): value(money) {}// private, force strong types.
public:
cMoney() : value(0) {}
cMoney(const cMoney& money): value(money.value) {}
// define user defined literals.
// I will accept money only in the below currencies.
// And We both are sure how much money we are dealing with.
friend cMoney operator"" _usd(long double val);
friend cMoney operator"" _inr(long double val);
};
cMoney operator"" _usd(long double val)
{
return cMoney(val);
}
cMoney operator"" _inr(long double val)
{
return cMoney(CurrencyConversion::ConvertTo<CurrencyConversion::INR, CurrencyConversion::USD>(val));
}
//...
cMoney m1(10); // ERROR! private constructor
cMoney m2(10.5_inr); // public user defined literal creates the object with appropriate conversion and then copy creates the object.
Run the above code here.
The same can be achieved without user defined literals too! for example, one class for each unit that gets the money in the desired unit. or with generic programming.
Is it really a deal breaker? I will leave that for you to decide! An interesting discussion on SO that answers possible questions is worth looking at.