0

I'm studying C++ and I found this weird syntax. What does &_ mean and why the author could use the variable as _1st?

std::sort(open_list.begin(), open_list.end(), [] (const auto &_1st, const auto &_2st) {
  return _1st->h_value + _1st->g_value < _2st->h_value + _2st->g_value
});

EDIT 1

I thought that in order to create a reference of a variable it was necessary to use ampersand operator followed by the name, like: & _1st(notice the blank space between them).

Is underscore a special way to declare name variables in C++?

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
Bruno
  • 348
  • 5
  • 21
  • 1
    The space after the `&` is not needed. Try it. – Pete Becker Jun 19 '19 at 04:29
  • 2
    Sidenote: [What are the rules about using an underscore in a C++ identifier?](https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) You don't run into problems breaking these rules very often but when you do, they are a serious mind. – user4581301 Jun 19 '19 at 04:30
  • 2
    Re: your edit, you can write either `auto& var` or `auto &var` or less common `auto & var` or worse still `auto&var`. They're all the same, though there's a difference between `int& var1, var2`, – Tas Jun 19 '19 at 05:16
  • Or even `auto (some insane amount of whitespace) & (even more insane amount of whitespace) var1` C++ doesn't care about whitespace at all. –  Jun 19 '19 at 05:50
  • `const auto & _1st` and `const auto &_1st` are the same. That's also the same as `const auto & _1st` and `const auto&_1st` and `const auto& _1st`. – Ben Jun 19 '19 at 16:47

5 Answers5

8

& is used for declaring references; so const auto &_1st is declaring a parameter named _1st, whose type is lvalue-reference (to const). It's same as const auto & _1st, and the spaces are superfluous; you can even write it as const auto&_1st, this is not special for underscores.

And note that underscores could be used for identifiers.

An identifier is an arbitrarily long sequence of digits, underscores, lowercase and uppercase Latin letters, and most Unicode characters (see below for details). A valid identifier must begin with a non-digit character (Latin letter, underscore, or Unicode non-digit character).

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
3

const auto &_1st

That declares a parameter with the name _1st. The & means that it's passed by reference to the function.

Sid S
  • 6,037
  • 2
  • 18
  • 24
3

Variables can be used only according to particular rules. It cannot directly start with a number, so the author has used _(underscore). Look into this : https://www.sitesbay.com/cpp/cpp-variable-declaration

Ampersand symbol is used for representing pass by reference.

S M Vaidhyanathan
  • 320
  • 1
  • 4
  • 13
1

The operation is & + variable_name, rather than &_ + variable_name.

In this context, & followed by a variable means passing the pointer of this variable as one of the function arguments. You will probably notice that in the code you pasted, the third very long argument of std::sort is actually a lambda expression( a function ):

[] (const auto &_1st, const auto &_2st) {
  return _1st->h_value + _1st->g_value < _2st->h_value + _2st->g_value
}

It corresponds to the third argument of sort from according to HERE, and below is a short quote:

comp

Binary function that accepts two elements in the range as arguments, and returns a value convertible to bool. The value returned indicates whether the element passed as first argument is considered to go before the second in the specific strict weak ordering it defines. The function shall not modify any of its arguments. This can either be a function pointer or a function object.

So basically when you want to sort a type of variable with your specifically defined rule or c++ does not know how to compare the target you are trying to sort, you have to define a function tells c++ how to perform sorting.

For details, you may also want to take a look at THIS.

There are few reasons to pass variables as reference pointers instead of passing by value. In many cases you just do not wanted to create additional memory consumption and save time, passing by reference allows you access values without make a copy. For details, please refer to HERE

Xinyao Wang
  • 2,029
  • 12
  • 24
0

This is just a naming convention to declare the variable which was written by someone in that code snippet.

So, _1st and _2nd just a reference variable of auto type.

Below code will also work fine:

std::sort(open_list.begin(), open_list.end(), [] (const auto &first, const auto &second) {
return first->h_value + first->g_value < second->h_value + second->g_value
});
Abhishek Sinha
  • 480
  • 4
  • 9