Автоматичне ключове слово C ++. Чому це магія?


145

З усього матеріалу, який я використовував для вивчення C ++, autoзавжди був дивний специфікатор тривалості зберігання, який не виконував ніяких цілей. Але зовсім недавно я зіткнувся з кодом, який використовував його як саме ім'я типу. З цікавості я спробував це, і він передбачає тип того, що мені трапляється, привласнити його!

Раптом ітератори STL і, ну, все, що використовує шаблони, в 10 разів простіше написати. Створюється враження, що я використовую "веселу" мову, як Python.

Де це моє ключове слово було все життя? Чи будете ви мріяти мої мрії, сказавши, що це ексклюзивно для візуальної студії чи не портативний?


18
це не. магія. Це нове ( о, ні, яка погана каламбур ). Тепер асинхронне майбутнє ( задуха )
sehe

2
Ось посилання на автоматичні ключові слова en.cppreference.com/w/cpp/language/auto
andyqee

Відповіді:


149

auto було ключовим словом, яке C ++ "успадкувало" від C, яке було там майже назавжди, але практично ніколи не використовувалось, оскільки існували лише дві можливі умови: або це не було дозволено, або ж воно було прийняте за замовчуванням.

Використання autoдля означання виведеного типу було новим із C ++ 11.

Одночасно auto x = initializerвиводить тип xз типу initializerтак само, як працює виведення типу шаблону для шаблонів функцій. Розглянемо такий шаблон функції:

template<class T>
int whatever(T t) { 
    // point A
};

У точці A тип був призначений на Tоснові значення, переданого параметру в whatever. Коли ви робите auto x = initializer;, однотипний відлік використовується для визначення типу для xтипу, initializerякий використовується для його ініціалізації.

Це означає, що більшість механізмів виведення типів, які компілятор потребує впровадженню auto, вже були присутніми і використовувались для шаблонів на будь-якому компіляторі, який навіть намагався реалізувати C ++ 98/03. Таким чином, додавати підтримку autoбуло, мабуть, досить просто для всіх команд-компіляторів - вона була додана досить швидко, і, мабуть, мало помилок, пов’язаних із цим.

Коли ця відповідь була спочатку написана (у 2011 році до того, як чорнило висохло за стандартом C ++ 11), autoбуло вже досить портативним. На сьогоднішній день він є повністю портативним серед усіх основних компіляторів. Єдиними очевидними причинами цього уникнути було б, якщо вам потрібно написати код, сумісний із компілятором C, або у вас є конкретна потреба орієнтуватися на якийсь компілятор ніші, який, на вашу думку, не підтримує (наприклад, кілька людей все ще пишуть код для MS-DOS з використанням компіляторів Borland, Watcom тощо, які не спостерігали значних оновлень протягом десятиліть). Якщо ви використовуєте досить поточну версію будь-якого з основних компіляторів, то немає жодних причин уникати цього.


24

Це просто взяти загальнокорисне ключове слово та надати йому новий, кращий функціонал. Він стандартний для C ++ 11, і більшість компіляторів C ++ з навіть деякою підтримкою C ++ 11 підтримуватимуть його.


Ой! Ага, ніколи не думав про мову С ++ як про річ, яка може змінитися сама по собі. Мені доведеться шукати, що ще вони додали в цьому C ++ 11, я чув трохи C ++ 0x, але ніколи не заглиблювався в нього занадто глибоко.
Енн Квінн

7
@Clairvoire C ++ 0x була тимчасовою назвою. Він був опублікований цього місяця, і таким чином став C ++ 11.
Р. Мартіньо Фернандес

13

Для змінних вказує, що тип змінної, яка оголошується, буде автоматично виведений з її ініціалізатора. Для функцій вказує, що тип повернення є заднім типом повернення або буде виведено з його операторів повернення (оскільки C ++ 14).

Синтаксис

auto variable initializer   (1) (since C++11)

auto function -> return type    (2) (since C++11)

auto function   (3) (since C++14)

decltype(auto) variable initializer (4) (since C++14)

decltype(auto) function (5) (since C++14)

auto :: (6) (concepts TS)

cv(optional) auto ref(optional) parameter   (7) (since C++14)

Пояснення

1) При оголошенні змінних в області блоку, в області простору імен, в операторах ініціалізації циклів тощо, ключове слово auto може використовуватися як специфікатор типу. Після того, як визначено тип ініціалізатора, компілятор визначає тип, який замінить ключове слово auto, використовуючи правила для виведення аргументу шаблону з виклику функції (детальну інформацію див. У виведенні аргументу шаблону # Інші контексти). Ключове слово auto може супроводжуватися модифікаторами, такими як const або &, які братимуть участь у виведенні типу. Наприклад, заданий const auto& i = expr;, тип i - це саме тип аргументу u в уявному шаблоні, template<class U> void f(const U& u)якщо функція викликаєf(expr) були складені. Таким чином, автоматичне && може бути виведене як посилання на значення значення або посилання на оцінку відповідно до ініціалізатора, який використовується в діапазоні для циклу. Якщо для декларування декількох змінних використовується авто, то виведені типи повинні відповідати. Наприклад,auto i = 0, d = 0.0; неправильно сформована, тоді як декларація auto i = 0, *p = &i; добре сформована, а автоматичне виводиться як int.

2) У оголошенні функції, яке використовує синтаксис типу зворотного повернення, ключове слово auto не виконує автоматичне визначення типу. Він виступає лише частиною синтаксису.

3) У оголошенні функції, що не використовує синтаксис типу зворотного повернення, ключове слово auto вказує, що тип повернення буде виведений з операнду його оператора повернення, використовуючи правила для виведення аргументу шаблону.

4) Якщо оголошеним типом змінної є decltype (auto), ключове слово auto замінюється виразом (або списком виразів) його ініціалізатора, а фактичний тип виводиться за допомогою правил decltype.

5) Якщо тип повернення функції оголошено decltype (auto), ключове слово auto замінюється операндом його оператора return, а фактичний тип повернення виводиться за допомогою правил для decltype.

6) Специфікатор вкладеного імені форми auto :: - це заповнювач, який замінюється класом або типом переліку, дотримуючись правил для вирахування заповнення типу обмеженого типу.

7) Декларація параметра в виразі лямбда. (оскільки C ++ 14) Декларація параметра функції. (поняття ТС)

Примітки До моменту C ++ 11, auto мав семантичний специфікатор тривалості зберігання. Змішування автоматичних змінних та функцій в одній декларації, як уauto f() -> int, i = 0; , заборонено.

Для отримання додаткової інформації: http://en.cppreference.com/w/cpp/language/auto


11

Ця функціональність існувала не все життя. Він підтримується у Visual Studio з версії 2010 року. Це нова функція C ++ 11, тому вона не є винятковою для Visual Studio і є / буде портативною. Більшість компіляторів це вже підтримують.


3

Він нікуди не дінеться ... це нова стандартна функція C ++ у впровадженні C ++ 11. Однак, це прекрасний інструмент для спрощення оголошень об'єкта, а також очищення синтаксису для певних парадигм викликів (тобто для діапазонів на основі діапазону), не перенавантажуйте і не зловживайте ним :-)


3

Ключове слово auto визначає, що тип змінної, яка оголошується, буде автоматично вилучена з її ініціалізатора. У разі функцій, якщо їх тип повернення є автоматичним, це буде оцінено за допомогою виразу типу повернення під час виконання.

Це може бути дуже корисно, коли нам доведеться використовувати ітератор. Наприклад, для коду нижче, ми можемо просто використовувати "auto", а не писати весь синтаксис ітератора.

int main() 
{ 

// Initialize set 
set<int> s; 

s.insert(1); 
s.insert(4); 
s.insert(2); 
s.insert(5); 
s.insert(3); 

// iterator pointing to 
// position where 2 is 
auto pos = s.find(3); 

// prints the set elements 
cout << "The set elements after 3 are: "; 
for (auto it = pos; it != s.end(); it++) 
    cout << *it << " "; 

return 0; 
}

Ось так ми можемо використовувати ключове слово "авто"


0

Це Magic - це можливість зменшити необхідність запису коду для кожного типу змінної, що передається певним функціям. Розглянемо функцію print (), схожу на Python, в її базі C.

#include <iostream>
#include <string>
#include <array>

using namespace std;

void print(auto arg) {
     cout<<arg<<" ";
}

int main()
{
  string f = "String";//tok assigned
  int x = 998;
  double a = 4.785;
  string b = "C++ Auto !";
//In an opt-code ASCII token stream would be iterated from tok's as:
  print(a);
  print(b);
  print(x);
  print(f);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.