I find the std::this_thread::sleep_for can process the time unit s.
std::this_thread::sleep_for(2s);
But I don't know what the s in 2s is.
What is s in std::this_thread::sleep_for(2s)?
s is a user-defined literal making 2s a literal value of type chrono::second.
Built-in literals
You might be familiar with integer literals and floating literals; those are built-in suffixes:
+--------+---------+---------------+
| Suffix | Example | Type |
+--------+---------+---------------+
| U | 42U | unsigned int |
| LL | 1LL | long long int |
| f | 3.14f | float |
+--------+---------+---------------+
They let you provide a literal value whose type matches your needs. For example:
int half(int n) { return n/2; }
float half(float f) { return f/2; }
half(3); // calls the int version, returns 1 (int)
half(3.f); // calls the float version, returns 1.5f (float)
User-defined literals
C++11 added a new feature: user-defined literal suffixes:
Allows integer, floating-point, character, and string literals to produce objects of user-defined type by defining a user-defined suffix.
Syntax
They allow to provide a literal of a user-defined type or a Standard Library-defined type. Defining a literal is as easy as defining the operator"":
// 0_<suffix> is now a <type> literal
<type> operator "" _<suffix>(unsigned long long); // ull: one of the height existing forms
Example
#include <iostream>
class Mass
{
double _value_in_kg;
public:
Mass(long double kg) : _value_in_kg(kg) {}
friend Mass operator+ (Mass const& m1, Mass const& m2) { return m1._value_in_kg + m2._value_in_kg; }
friend std::ostream& operator<<(std::ostream& os, Mass const& m) { return os << m._value_in_kg << " kg"; }
};
Mass operator "" _kg(long double kg) { return Mass{kg}; }
Mass operator "" _lb(long double lb) { return Mass{lb/2.20462}; }
int main()
{
std::cout << 3.0_kg + 8.0_lb << '\n';
}
Outputs "6.62874 kg" (demo) as it should.
The case of std::chrono
Unlike "real" user-provided literals, the Standard Library provides literals not starting with an underscore (_). s is one of them and is defined in <chrono> (since C++14):
constexpr chrono::seconds operator "" s(unsigned long long secs);
With other duration literals, it let you write something as pretty as:
#include <chrono>
using namespace std::chrono_literals;
const auto world_marathon_record_2018 = 2h + 1min + 39s;
"s" stands for second and actually a literal operator defined in standard library. Literals are part of C++14 standard. You may access them by using namespace std::chrono_literals;
s in this expression is actually a chrono library function which is defined in Standard library
Related
I'm learning about user-defined literals, and confused with the following test code:
std::chrono::seconds operator"" _s(unsigned long long s) {
return std::chrono::seconds(s);
}
std::string operator"" _str(const char *s, std::size_t len) {
return std::string(s, len);
}
int main() {
auto str = "xxxxx"_str;
std::cout << str.size() << std::endl; // works
auto sec = 4_s;
std::cout << sec.count() << std::endl; // works
std::cout << "xxxxx"_str.size() << std::endl; // works
std::cout << 4_s.count() << std::endl; // does **NOT** work!
return 0;
}
The compiler gives the following error message:
error: no matching literal operator for call to 'operator""_s.count' with argument of type 'unsigned long long' or 'const char *', and no matching literal operator template
cout << 4_s.count() << endl;
It seems that it takes _s.count as a user-defined literal. Also, a floating-point literal behaves like an integer literal.
Why do user-defined integer literals and string literals have different behavior?
That's how floating point literals work!!
Add a pair of parentheses and it should work:
std::cout << (4_s).count();
Or alternatively, separate them (to stop the compiler from interpreting it as an ill-formed fractional constant floating point literal):
std::cout << 4_s .count();
// ^ Space here!
Reference: CppReference.com
In the Notes section of the reference above,
Due to maximal munch, user-defined integer and floating point literals ending in [p, P, (since C++17)] e and E, when followed by the operators + or -, must be separated from the operator with whitespace in the source:
long double operator""_E(long double);
long double operator""_a(long double);
int operator""_p(unsigned long long);
auto x = 1.0_E+2.0; // error
auto y = 1.0_a+2.0; // OK
auto z = 1.0_E +2.0; // OK
auto w = 1_p+2; // error
auto u = 1_p +2; // OK
So when it comes to dot, which is used as decimal point, it must be separated from anything behind, or it'll be treated as part of the floating point number.
I have tested the example above from CppReference and got a very similar error message:
test.cpp:19:10: error: unable to find numeric literal
operator 'operator""_E+2.0'
^^^^^^
auto x = 1.0_E+2.0; // error
Got the point how _E+2.0 is considered as a whole ud-suffix?
My original explanation attempt can be found in the revision history of this post.
I'm learning about user-defined literals, and confused with the following test code:
std::chrono::seconds operator"" _s(unsigned long long s) {
return std::chrono::seconds(s);
}
std::string operator"" _str(const char *s, std::size_t len) {
return std::string(s, len);
}
int main() {
auto str = "xxxxx"_str;
std::cout << str.size() << std::endl; // works
auto sec = 4_s;
std::cout << sec.count() << std::endl; // works
std::cout << "xxxxx"_str.size() << std::endl; // works
std::cout << 4_s.count() << std::endl; // does **NOT** work!
return 0;
}
The compiler gives the following error message:
error: no matching literal operator for call to 'operator""_s.count' with argument of type 'unsigned long long' or 'const char *', and no matching literal operator template
cout << 4_s.count() << endl;
It seems that it takes _s.count as a user-defined literal. Also, a floating-point literal behaves like an integer literal.
Why do user-defined integer literals and string literals have different behavior?
That's how floating point literals work!!
Add a pair of parentheses and it should work:
std::cout << (4_s).count();
Or alternatively, separate them (to stop the compiler from interpreting it as an ill-formed fractional constant floating point literal):
std::cout << 4_s .count();
// ^ Space here!
Reference: CppReference.com
In the Notes section of the reference above,
Due to maximal munch, user-defined integer and floating point literals ending in [p, P, (since C++17)] e and E, when followed by the operators + or -, must be separated from the operator with whitespace in the source:
long double operator""_E(long double);
long double operator""_a(long double);
int operator""_p(unsigned long long);
auto x = 1.0_E+2.0; // error
auto y = 1.0_a+2.0; // OK
auto z = 1.0_E +2.0; // OK
auto w = 1_p+2; // error
auto u = 1_p +2; // OK
So when it comes to dot, which is used as decimal point, it must be separated from anything behind, or it'll be treated as part of the floating point number.
I have tested the example above from CppReference and got a very similar error message:
test.cpp:19:10: error: unable to find numeric literal
operator 'operator""_E+2.0'
^^^^^^
auto x = 1.0_E+2.0; // error
Got the point how _E+2.0 is considered as a whole ud-suffix?
My original explanation attempt can be found in the revision history of this post.
I am trying to do a simple library where the object is a point on the xy-axis.
I want to be able to use literals like this:
Point a = (3,4);
where (3,4) is a point literal.
I read about user defined literals, but (as I understood) this seems to be impossible.
May be "(3,4)"_P is possible as I understand it.
However, I found on this page interesting use of user defined literals as follows:
#include <iostream>
#include <complex>
int main()
{
using namespace std::complex_literals;
std::complex<double> c = 1.0 + 1i;
std::cout << "abs" << c << " = " << abs(c) << '\n';
}
I can under stand the part 1i as a user defined literal, but not the whole thing 1.0 + 1i.
What I am missing, and what is the nearest possible way of getting a literal similar to (x,y) without using ".
As Some programmer dude shows, the best way is to use uniform initialization.
However, just for the fun of it, you can (sort of) do this with User Defined Literals. My idea is to to have 2 literals for each coordinate and overload operator+ between them to create the point.
Remember, this is just for fun, don't use this in a real code:
struct Px { int x; };
struct Py { int y; };
struct Point {
int x;
int y;
};
constexpr auto operator""_px(unsigned long long x) -> Px { return Px{(int)x}; }
constexpr auto operator""_py(unsigned long long y) -> Py { return Py{(int)y}; }
constexpr auto operator+(Px x, Py y) -> Point { return Point{x.x, y.y}; }
then you can have:
auto p = 3_px + 4_py; // p is deduced to type `Point`
Of course this is just a rough framework. Read this great article to learn more about UDLs. You would need to deal with the narrowing conversion in a better way and propper use namespaces to make it a better solution.
As a bonus, you could also use operator, to create a syntax more appropriate to what you had in mind. But, don't do this, as overloading operator, is just evil:
auto operator,(Px x, Py y) -> Point { return Point{x.x, y.y}; }
auto p = (2_px, 1_py); // p is deduced to type `Point`
You can't make up literals on your own, only create suffixes for literals. Like the shown 1i or the standard language f as in 1.0f. (See e.g. this user-defined literal reference for more information.)
What you can to is to use uniform initialization doing something like
Point a = { 3, 4 }; // note the use of curly-braces
Depending on what Point is you might need to add a suitable constructor to make it work.
You have 3 options
Point p = { 1,2 };
Point p2{ 1,2 };
Point p3(1,2);
A little while ago I had an idea about "parameterized" user-defined literals and was wondering if there is any way to do this in the current C++ standard.
Basically, the idea is to have a user-defined literal whose behaviour can be tweaked according to some parameters. As a simple example, I chose a "fixed-point" literal which turns a floating-point number into an integer; the parameter is the precision in terms of the number of decimal places.
This is just an exercise for now, since I'm not sure how or if this would be useful in a real application.
My first idea went something like this:
namespace fp_impl {
constexpr int floor(long double n) {
return n;
}
constexpr int pow10(int exp) {
return exp == 0 ? 1 : 10 * pow10(exp - 1);
}
template<int i>
constexpr int fixed_point(long double n) {
return floor(n * pow10(i));
}
namespace fp2 {
constexpr int operator"" _fp (long double n) {
return fixed_point<2>(n);
}
}
namespace fp4 {
constexpr int operator"" _fp (long double n) {
return fixed_point<4>(n);
}
}
}
template<int prec> struct fp;
template<> struct fp<2> {
namespace lit = fp2;
};
template<> struct fp<4> {
namespace lit = fp4;
};
int main() {
{
using namespace fp<2>::lit;
std::cout << 5.421_fp << std::endl; // should output 542
}
{
using namespace fp<4>::lit;
std::cout << 5.421_fp << std::endl; // should output 54210
}
}
However, it doesn't compile because namespace aliases are not permitted at class scope. (It also has a problem with requiring you t manually define every version of operator"" _fp.) So I decided to try something with macros:
namespace fp {
namespace detail {
constexpr int floor(long double n) {
return n;
}
constexpr int pow10(int exp) {
return exp == 0 ? 1 : 10 * pow10(exp - 1);
}
template<int i>
constexpr int fixed_point(long double n) {
return floor(n * pow10(i));
}
}
}
#define SPEC(i) \
namespace fp { \
namespace precision##i { \
constexpr int operator"" _fp(long double n) { \
return fp::detail::fixed_point<i>(n); \
} \
} \
}
SPEC(2); SPEC(4);
#undef SPEC
#define fp_precision(i) namespace fp::precision##i
int main() {
{
using fp_precision(2);
std::cout << 5.421_fp << std::endl;
}
{
using fp_precision(4);
std::cout << 5.421_fp << std::endl;
}
}
This works, though it still has the requirement of using the SPEC() macro for every precision you ever want to use. Of course, some preprocessor trickery could be used to do this for every value from, say, 0 to 100, but I'm wondering if there could be anything more like a template solution, where each one is instantiated as it is needed. I had a vague idea of using an operator"" declared as a friend function in a template class, though I suspect that won't work either.
As a note, I did try template<int i> constexpr int operator"" _fp(long double n), but it seems this is not an allowed declaration of a literal operator.
You can return a class type that has operator()(int) overloaded from your literal operator. Then you could write
5.421_fp(2);
A user-defined literal function takes as its sole argument the literal itself. You can use state outside the function, for example with a global or thread-local variable, but that's not very clean.
If the argument will always be compile-time constant, and it's part of the number, pass it through the literal itself. That requires writing an operator "" _ ( char const *, std::size_t ) overload or template< char ... > operator "" _ () template and parsing the number completely by yourself.
You will have to work such a parameter into the existing floating-point grammar, though. Although C++ defines a very open-ended preprocessing-number construct, a user-defined literal must be formed from a valid token with a ud-suffix identifier appended.
You might consider using strings instead of numbers, but then the template option goes away.
One does not need macros to solve the problem. Since the problem concerns processing literals numbers (e.g., integers or floating-point formatted numbers), one can use the template definition of the literal operator and template metaprogramming to do the job completely at compile-time.
To do your fixed-point literal conversions, you could use the integer literal operator with unsigned long long, e.g.,
some_type operator "" _fp(unsigned long long num)
{
// code
}
(or with long double with possible loss of precision) but this causes everything to happen at run-time.
C++11 in section 2.14.8 (User-defined Lierals [lex.ext]) within paragraphs 3 and 4 define literal operator variations including a template version for integer and floating-point literals! Unfortunately, paragraphs 5 and 6 do not define a template version for string and character literals. This means this technique will only work with integer and floating-point literals.
From C++11 section 2.14.8 the above _fp literal operator can therefore be written instead as:
template <char... Digits>
constexpr some_type operator "" _fp()
{
return process_fp<2, Digits...>::to_some_type();
}
e.g., where the 2 is a value from the int i template parameter from the OP and some_type is whatever the return type needs to be. Notice that template parameter is a char --not an int or some other number. Also notice that the literal operator has no arguments. Thus code like Digit - '0' is needed to get the numeric value to an integer value for that character. Moreover, Digits... will be processed in a left-to-right order.
Now one can use template metaprogramming with process_fp whose forward declaration would look like:
template <int i, char... Digits>
struct process_fp;
and would have a static constexpr method called to_some_type() to compute and return the desired, compile-time result.
One might also want a meaningful, simple example of this is done. Last year I wrote code (link below) that when used like this:
int main()
{
using namespace std;
const unsigned long long bits =
11011110101011011011111011101111_binary;
cout << "The number is: " << hex << bits << endl;
}
would convert the binary number 11011110101011011011111011101111 into an unsigned long long at compile-time and store it into bits. Full code and explanation of such using the template metaprogramming technique referred to above is provided in my blog entry titled, Using The C++ Literal Operator.
Can functions be used with user defined literals?
If so, what shenanigans can be done? Is this legal?
void operator "" _bar(int (*func)(int)) {
func(1);
}
int foo(int x) {
std::cout << x << std::endl;
}
int main() {
foo(0); // print 0
foo_bar; // print 1
}
According to the C++11 Feb 2011 Draft § 2.14.8, the user literal types are integer-literals, floating-literals, string-literals, and character-literals. There is no way to do a function-literal type.
A user-defined-literal is treated as a call to a literal operator or
literal operator template (13.5.8). To determine the form of this call
for a given user-defined-literal L with ud-suffix X, the
literal-operator-id whose literal suffix identifier is X is looked up
in the context of L using the rules for unqualified name lookup
(3.4.1). Let S be the set of declarations found by this lookup. S
shall not be empty.
Integers:
operator "" X (n ULL)
operator "" X ("n")
operator "" X <’c1’, ’c2’, ... ’ck’>()
Floating:
operator "" X (f L)
operator "" X ("f")
operator "" X <’c1’, ’c2’, ... ’ck’>()
String:
operator "" X (str, len)
operator "" X <’c1’, ’c2’, ... ’ck’>() //unoffcial, a rumored GCC extension
Character:
operator "" X (ch)
Look at foo_bar, its just a single lexical token. Its interpreted as a single identifier named foo_bar, not as foo suffixed with _bar.
No.
C++ intentionally avoids such shenanigans since the symbol foo_bar would be very difficult to comprehend if it weren't defined immediately before its use in your example.
You could achieve something similar with the preprocessor.
#define bar (1)
int foo(int x) {
std::cout << x << std::endl;
}
int main() {
foo(0); // print 0
foo bar; // print 1
}
I don't know if this adds anything but there's nothing preventing you from defining
PythonScript operator"" _python(const char*, std::size_t len) {...}
R"Py(
print "Hello, World"
)Py"_python;
I actually think user-defined literals would make a nice way to embed scripts or SQL.