Как определяется тип инициализируемой переменной при использовании ключевого слова auto
?
В каких случаях переменная окажется константной, ссылкой, указателем, или всё это в различных комбинациях?
Как повлияют на эти правила дополнительные указания, типа const auto
, auto&
, const auto&
(и ещё наверное аналогичные с указателями, может даже с двойными указателями, и с &&
)?
Правила вывода очень похожи на правила для функций вроде template <typename T> void foo(T)
.
[const] [volatile] auto
- никогда не будет ссылкой, никакие cv-квалификаторы (const
, volatile
) автоматически не добавляются.
Особый случай - если такую переменную инициализировать = {a,b,c}
- то тип будет [const] [volatile] std::initializer_list<T>
.
[const] [volatile] auto &
- cv-квалификаторы добавляются автоматически (кроме случая, когда его инициализируют rvalue - тогда без указания const
будет ошибка).
int a = 1;
const int b = 1;
auto &x = a; // int &x
auto &y = b; // const int &y
auto &z = 1; // Ошибка, хотя `const int &z = 1` скомпилировалось бы.
const auto &w = 1; // const int &w
[const] [volatile] auto &&
- если указан хотя бы один cv-квалификатор, то работает по аналогии с auto &
, но для rvalue.
Если cv-квалификаторы не указаны, то работает как forwarding ссылка:
MyClass a = 1;
const MyClass b = 1;
auto &&x = a; // MyClass &x
auto &&x = b; // const MyClass &x
auto &&x = MyClass(); // MyClass &&x
auto &&x = (const MyClass) MyClass(); // const MyClass &&x
[const] [volatile] auto &&
, так же как и auto
, умеет работать с initializer_list
:
auto &&x = {1,2,3}; // std::initializer_list<int> &&
Во всех случаях выше, если переменную инициализировать {a}
(без =
), то auto
ведет себя так же, как если бы инициализатор был = a
. В фигурных скобках должен быть только один элемент.
auto
может упоминаться в более сложных конструкциях: можно делать указатели на auto
, указатели-на-члены, и ссылки на них. Разрешаются указатели на указатели, указатели на функции, и т.д. Но массивы с auto
почему-то нельзя делать.
Если сделать указатель на auto
, то cv-квалификаторы добавляются автоматически:
const int x = 1;
auto *y = &x; // const int *y
Есть еще decltype(auto)
. Он похож на auto
, но на него нельзя формировать ссылки и указатели, и нельзя указывать cv-квалификаторы.
Он использует те же правила вывода, что и decltype
.
Он особенно хорошо подходит для написания оберток для функций:
decltype(auto) foo(бла бла)
{
return bar(бла бла);
}
Здесь возвращаемый тип bar
копируется в foo
, даже если это ссылка.
const int n = 5;
auto m = n; // int
const int& p = n;
auto q = p; //int
const std::vector<int> v(1);
auto a = v[0]; // int
decltype(a) d ; // int, тип сущности, именованной как d
decltype(v[0]) b = 1; // const int& (возвращаемое значение
// std::vector<int>::operator[](size_type) const)
decltype((a)) ref = a; // int&, так как (a) является lvalue
auto value = ref; //int
++ref; // ошибка
++value; //правильно
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Сап! Объясните максимально подробно, пожалуйста, что именно делают delete и nullptr для указателейВот код:
Так вот я не понимаю,зачем писать WNDCLASSEX после обЪявления структуры,вычитал где то что это создание объекта,то есть ,будто бы мы объявили WNDCLASSEX...
Пытаюсь писать простой перцептрон, который имеет только 2 вход и 1 выход и не имеет никаких скрытых слоевПерцептрон должен выполнять функцию...