Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the correct argument type for std::less<int>?

Tags:

c++

templates

I am making a class -- a BST -- that can compare templated nodes, which require a comparator, such as std::less.

the tree is like so :

template<typename T, typename comparator>
class tree
{
private:
    comparator compare;
public:
    explicit tree (comparator functor);
};

But I can't seem to find which template type I should input in my application.

tree<int> my_bst (std::less<int>);

error: wrong number of template arguments (1, should be 2)
 bst::tree<int> my_bst (std::less<int>);

And it makes sense because my template type is incomplete.

How should I profile my constructor?

What is named that property of the templates? Because all I find about that is the sort page on cppreference.

Typically, I can use sort like so

std::vector<int> v;
std::sort(v.begin (), v.end (), std::less<>());

How come the specialization of less is deduced? How can I replicate that?

like image 608
Pierre-Antoine Guillaume Avatar asked Oct 01 '18 20:10

Pierre-Antoine Guillaume


People also ask

Does a class template need to have a type argument?

A class template does not need to have a type argument if it has non-type arguments. For example, the following template is a valid class template: Again, these two declarations refer to distinct classes because the values of their non-type arguments differ.

What are the requirements for non-type address arguments?

For non-type address arguments, the type of the instance argument must be of the form identifier or & identifier , and the type of the instance argument must match the template parameter exactly, except that a function name is changed to a pointer to function type before matching.

What is the difference between instance argument and template parameter?

For non-type integral arguments, the instance argument matches the corresponding template parameter as long as the instance argument has a value and sign appropriate to the parameter type.

How do you compare two values in STL?

For example, std::sort compares values two by two to determine which one goes before the other. To perform those comparisons, STL algorithms have a default way of doing it, such as operator< or operator== (depending on whether they use equality or equivalence ).


1 Answers

To save yourself, and everyone else that just wants a default behavior, the extra keystrokes in telling the compiler the type of the comparator you could instead set it by default and then you only have to specify it if you want a different behavior.

template<typename T, typename comparator = std::less<T>>
class tree
{
private:
    comparator compare;
public:
    explicit tree (comparator functor = comparator{});
};

Will default comparator to the type std::less<T> and lets you construct the class like

tree<int> my_bst;

Then, if you want to use a different type, like std::greater, then you would use

tree<int, std::greater<int>> my_bst;

As you have it right now you would have to use

tree<int, std::less<int>> my_bst(std::less<int>{});
          ^^^^^^^^^^^^^^         ^^^^^^^^^^^^^^^^
          |                      pass an instance of the comparator to the constructor
          |
          tell the compiler the type of the comparator

to make a tree using std::less<int>.


As for why you can do

std::vector<int> v;
std::sort(v.begin (), v.end (), std::less<>());

std::less has been specialized for std::less<void> in C++14 and it provides an operator () that is templated and will deduce the types passed to it. That means an object of std::less<> can compare any two types so long as the expression

decltype(std::forward<T>(lhs) < std::forward<U>(rhs))

is valid where both T and U are parameter types to the operator ().

like image 78
NathanOliver Avatar answered Oct 22 '22 09:10

NathanOliver