C++11 user-defined literals and some constructions
I was taking a look at the proposal N2765 (user-defined literals) already implemented on the development snapshots of the GCC 4.7 and I was thinking in how user-defined literals can be used to create some interesting and sometimes strange constructions.
Introduction to user-defined literals
C++03 has some literals, like the “f” in “12.2f” that converts the double value to float. The problem is that these literals aren’t very flexible since they’re pretty fixed, so you can’t change them or create new ones. To overcome this situation, C++11 introduced the concept of “user-defined literals” that will give to the user, the ability to create new custom literal modifiers. The new user-defined literals can create either built-in types (e.g. int) or user-define types (e.g. classes), and the fact that they could be very useful is an effect that they can return objects instead of only primitives.
The new syntax for the user-defined literals is:
[enlighter lang=”C++”]
OutputType operator “” _suffix(const char *literal_string);
[/enlighter]
… in the case of a literal string. The OutputType is anything you want (object or primitive), the “_suffix” is the name of the literal modifier, isn’t required to use the underline in front of it, but if you don’t use you’ll get some warnings telling you that suffixes not preceded by the underline are reserved for future standardization.
Examples
Kmh to Mph converter
[enlighter lang=”C++” escaped=”true” lines=”1000″]
// stupid converter class
class Converter
{
public:
Converter(double kmph) : m_kmph(kmph) {};
~Converter() {};
double to_mph(void)
{ return m_kmph / 1.609344; }
private:
double m_kmph;
};
// user-defined literal
Converter operator “” kmph(long double kmph)
{ return Converter(kmph); }
int main(void)
{
std::cout << “Converter: ” << (80kmph).to_mph() << std::endl;
// note that I’m using parenthesis in order to
// be able to call the ‘to_mph’ method
return 0;
}
[/ccb]
Note that the literal for for numeric types should be either long double (for floating point literals) or unsigned long long (for integral literals). There is no signed type, because a signed literal is parsed as an expression with a sign as unary prefix and the unsigned number part.
std::string literal
[enlighter lang=”C++” escaped=”true” lines=”1000″]
std::string operator “” s (const char* p, size_t n)
{ return std::string(p,n); }
int main(void)
{
std::cout << "convert me to a string"s.length() << std::endl;
// here you don't need the parenthesis, note that the
// c-string was automagically converted to std::string
return 0;
}
[/ccb]
system() call
[enlighter lang=”C++” escaped=”true” lines=”1000″]
int operator “” ex(const char *cmd, size_t num_chars)
{ return system(cmd); }
int main(void)
{
“ls -lah”ex;
return 0;
}
[/ccb]
alias and std::map
[enlighter lang=”C++” escaped=”true” lines=”1000″]
typedef std::map
MyMap create_map()
{
MyMap m;
m[“lol”] = 7;
return m;
}
auto m = create_map();
int& operator “” m(const char *key, size_t length)
{ return m[key]; }
int main(void)
{
std::cout << "lol"m << std::endl;
// 7
"lol"m = 2;
std::cout << "lol"m << std::endl;
// 2
return 0;
}
[/ccb]
std::cout << "convert me to a string"s.length() << std::endl;
Ugh, I hate that syntax, I'd much rather something like this:
std::cout << "convert me to a string".tostring().length() << std::endl;
You are somewhat missing the point. Alongside the fact that wouldn’t be possible in C++ without casting, or somehow converting to an object first.
Adam, converting what to an object ? What example are you talking about ? What point Am I missing ?
@Christian: Converting the string to an object. In C++, string literals, e.g. “Hello” are not of type std::string, they are of type (const char[N]) where N is the length of the string (including null-terminator). To get something like “Hello”.length() to work would require casting or converting the string literal into a user defined object.
@Peter of course Peter ! Where Am I doing “Hello”.length() ?
Omg, just now I saw that there is another Chris here lol.
last example, line 17, replace
“lol”n = 2;
with
“lol”m = 2;
Fixed, thanks !
In fact when someone doesn’t know afterward its up
to other users that they will help, so here it occurs.
The Small Freestanding Bath And Back To Wall Combo.
The FERC has a tremendous amount of pipeline experience,
as they are responsible for the oversight of natural gas pipeline projects.
One more thing that you need to give thought to is working with
all of the information that toto singapore has to provide to you.