Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

C++ : curly brackets with std library type

I try to understand the docs for std::less, where the following example is given for the usage with a template.

#include <functional>
#include <iostream>
 
template <typename A, typename B, typename C = std::less<>>
bool fun(A a, B b, C cmp = C{})
{
    return cmp(a, b);
}
 
int main()
{
    std::cout
      << std::boolalpha
      << fun(1, 2)   << ' ' // true
      << fun(1.0, 1) << ' ' // false
      << fun(1, 2.0) << ' ' // true
      << std::less<int>{}(5, 5.6)    << ' ' // false: 5 < 5 (warn: implicit conversion)
      << std::less<double>{}(5, 5.6) << ' ' // true: 5.0 < 5.6
      << std::less<int>{}(5.6, 5.7)  << ' ' // false: 5 < 5 (warn: implicit conversion)
      << std::less{}(5, 5.6)         << ' ' // true: less<void>: 5.0 < 5.6
      << '\n';
}

Output:

true false true false true false true

My question is:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

How is a std:: function used as a template argument?

And in this concrete case, why are there curly brackets {} behind the C cmp = C or in the call std::less<double>{}(5, 5.6)?

>Solution :

This demo-code suffers from so-called ‘uniform initialisation’ (broken by design, be careful with its use especially in template code!), classic way to write the same code before uniform initialisation is:

std::less<int>()(5, 5.6); // others analogously

std::less is a callable class, a so-called ‘functor’, which means it provides an operator() by which objects of the class can be called just like a function (to be precise: the operator is a member function that gets called, just the syntax for getting called actually is the same).

The code presented now first constructs such an object (calls the constructor; first pair of parentheses) while afterwards the so constructed object is called (the operator() with two arguments, second pair of parentheses).

Equivalent code could be:

std::less<int> li; // note that the parentheses need to be left out;
                   // braces for uniform initialisation could remain
li(5, 5.6);

Note, though, that the life-time of the object li is now longer is longer (until leaving the current scope) than the one of the temporary (only current expression). In given case, there are no visible side effects, though, notably as std::less doesn’t have any in its destructor.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading