C ++ kata kunci otomatis. Mengapa ini ajaib?

144

Dari semua materi yang saya gunakan untuk belajar C ++, autoselalu menjadi specifier durasi penyimpanan aneh yang tidak melayani tujuan apa pun. Tapi baru-baru ini, saya menemukan kode yang menggunakannya sebagai nama ketik di dan dari dirinya sendiri. Karena penasaran saya mencobanya, dan mengasumsikan jenis apa pun yang saya tetapkan untuk itu!

Tiba-tiba STL iterator dan, yah, apa pun yang menggunakan template adalah 10 kali lipat lebih mudah untuk ditulis. Rasanya seperti saya menggunakan bahasa 'menyenangkan' seperti Python.

Di mana kata kunci ini sepanjang hidup saya? Akankah Anda menghancurkan impian saya dengan mengatakan itu eksklusif untuk studio visual atau tidak portabel?

Anne Quinn
sumber
18
ini bukan. sihir. Ini baru ( oh noes, sungguh pelesetan ). Sekarang async adalah masa depan ( terkesiap )
sehe
2
Berikut ini adalah referensi tentang kata kunci otomatis en.cppreference.com/w/cpp/language/auto
andyqee

Jawaban:

149

auto adalah kata kunci yang C + + "warisi" dari C yang telah ada di sana hampir selamanya, tetapi sebenarnya tidak pernah digunakan karena hanya ada dua kondisi yang mungkin: apakah tidak diizinkan, atau diasumsikan secara default.

Penggunaan autoberarti jenis yang disimpulkan adalah baru dengan C ++ 11.

Pada saat yang sama, auto x = initializermenyimpulkan tipe dari xtipe initializerdengan cara yang sama seperti pengurangan tipe templat bekerja untuk templat fungsi. Pertimbangkan templat fungsi seperti ini:

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

Pada titik A, suatu tipe telah ditetapkan Tberdasarkan nilai yang diteruskan untuk parameter whatever. Ketika Anda melakukannya auto x = initializer;, deduksi tipe yang sama digunakan untuk menentukan tipe xdari tipe initializeryang digunakan untuk menginisialisasi itu.

Ini berarti bahwa sebagian besar jenis mekanisme deduksi yang perlu diimplementasikan oleh kompiler autosudah ada dan digunakan untuk templat pada kompiler apa pun yang bahkan semacam berusaha untuk mengimplementasikan C ++ 98/03. Dengan demikian, menambahkan dukungan untuk autotampaknya cukup mudah untuk semua tim penyusun - itu ditambahkan dengan cukup cepat, dan tampaknya ada beberapa bug yang terkait dengannya juga.

Ketika jawaban ini awalnya ditulis (pada tahun 2011, sebelum tinta kering pada standar C ++ 11) autosudah cukup portabel. Saat ini, ini sepenuhnya portabel di antara semua kompiler arus utama. Satu-satunya alasan yang jelas untuk menghindarinya adalah jika Anda perlu menulis kode yang kompatibel dengan kompiler C, atau Anda memiliki kebutuhan khusus untuk menargetkan beberapa kompiler niche yang Anda tahu tidak mendukungnya (mis., Beberapa orang masih menulis kode untuk MS-DOS menggunakan kompiler dari Borland, Watcom, dll, yang belum melihat peningkatan yang signifikan dalam beberapa dekade). Jika Anda menggunakan versi terbaru dari salah satu kompiler arus utama, tidak ada alasan untuk menghindarinya sama sekali.

Jerry Coffin
sumber
23

Hanya menggunakan kata kunci yang umumnya tidak berguna dan memberikannya fungsionalitas baru yang lebih baik. Ini standar dalam C ++ 11, dan sebagian besar kompiler C ++ dengan bahkan beberapa dukungan C ++ 11 akan mendukungnya.

Nicol Bolas
sumber
Oh! Aha, tidak pernah menganggap bahasa C ++ sebagai sesuatu yang bisa berubah dengan sendirinya. Aku harus mencari apa lagi yang mereka tambahkan di C ++ 11 ini, aku mendengar sedikit C ++ 0x tetapi tidak pernah menggali terlalu dalam.
Anne Quinn
7
@Clairvoire C ++ 0x adalah nama sementara. Sudah diterbitkan bulan ini, dan dengan demikian menjadi C ++ 11.
R. Martinho Fernandes
13

Untuk variabel, tentukan bahwa tipe variabel yang dideklarasikan akan secara otomatis dideduksi dari inisialisasi. Untuk fungsi, tentukan bahwa tipe return adalah tipe trailing return atau akan dideduksi dari pernyataan pengembaliannya (karena C ++ 14).

Sintaksis

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)

Penjelasan

1) Ketika mendeklarasikan variabel dalam lingkup blok, dalam lingkup namespace, dalam pernyataan inisialisasi untuk loop, dll., Kata kunci otomatis dapat digunakan sebagai penentu jenis. Setelah jenis penginisialisasi telah ditentukan, kompiler menentukan jenis yang akan menggantikan kata kunci otomatis menggunakan aturan untuk pengurangan argumen template dari panggilan fungsi (lihat pengurangan argumen template # Konteks lain untuk detail). Kata kunci otomatis dapat disertai oleh pengubah, seperti const atau &, yang akan berpartisipasi dalam pengurangan jenis. Sebagai contoh, diberikan const auto& i = expr;, tipe i persis tipe argumen u dalam templat imajiner template<class U> void f(const U& u)jika fungsinya memanggilf(expr)dikompilasi. Oleh karena itu, auto && dapat disimpulkan sebagai referensi nilai atau referensi nilai sesuai dengan inisialisasi, yang digunakan dalam rentang berbasis untuk loop. Jika otomatis digunakan untuk mendeklarasikan beberapa variabel, tipe yang disimpulkan harus cocok. Misalnya, deklarasi tersebut terbentuk dengan baik dan otomatis disimpulkan sebagai int.auto i = 0, d = 0.0; adalah bentukan, sedangkan deklarasi auto i = 0, *p = &i;

2) Dalam deklarasi fungsi yang menggunakan sintaks tipe trailing return, kata kunci otomatis tidak melakukan deteksi tipe otomatis. Ini hanya berfungsi sebagai bagian dari sintaks.

3) Dalam deklarasi fungsi yang tidak menggunakan sintaks tipe trailing return, kata kunci otomatis menunjukkan bahwa tipe kembali akan dideduksi dari operan pernyataan pengembalian menggunakan aturan untuk pengurangan argumen templat.

4) Jika tipe variabel yang dideklarasikan adalah tipe pernyataan (otomatis), kata kunci otomatis diganti dengan ekspresi (atau daftar ekspresi) dari penginisialisasi, dan jenis yang sebenarnya dideduksi menggunakan aturan untuk decltype.

5) Jika tipe kembalinya fungsi dideklarasikan decltype (otomatis), kata kunci auto diganti dengan operan dari pernyataan pengembaliannya, dan tipe pengembalian aktual disimpulkan menggunakan aturan untuk decltype.

6) Penspesifikasi nama-nama dari form auto :: adalah placeholder yang digantikan oleh kelas atau tipe enumerasi mengikuti aturan untuk pengurangan placeholder tipe terbatas.

7) Deklarasi parameter dalam ekspresi lambda. (sejak C ++ 14) Deklarasi parameter fungsi. (konsep TS)

Catatan Sampai C ++ 11, otomatis memiliki semantik dari specifier durasi penyimpanan. Mencampur variabel dan fungsi otomatis dalam satu deklarasi, karena dalam auto f() -> int, i = 0;tidak diperbolehkan.

Untuk info lebih lanjut: http://en.cppreference.com/w/cpp/language/auto

Sadar Prathamesh
sumber
11

Fungsi ini belum ada seumur hidup Anda. Sudah didukung di Visual Studio sejak versi 2010. Ini adalah fitur C ++ 11 yang baru, jadi ini tidak eksklusif untuk Visual Studio dan portabel. Sebagian besar kompiler sudah mendukungnya.

R. Martinho Fernandes
sumber
3

Ini tidak akan kemana-mana ... ini adalah fitur standar C ++ baru dalam implementasi C ++ 11. Yang sedang berkata, sementara itu adalah alat yang luar biasa untuk menyederhanakan deklarasi objek serta membersihkan sintaks untuk paradigma panggilan tertentu (yaitu, range-for-loop berdasarkan), jangan berlebihan / menyalahgunakannya :-)

Jason
sumber
3

Kata kunci otomatis menentukan bahwa jenis variabel yang sedang dideklarasikan akan secara otomatis dikurangi dari penginisialisasi. Dalam hal fungsi, jika tipe pengembaliannya otomatis maka itu akan dievaluasi dengan ekspresi tipe pengembalian saat runtime.

Ini bisa sangat berguna ketika kita harus menggunakan iterator. Untuk mis untuk kode di bawah ini kita cukup menggunakan "auto" daripada menulis sintaks iterator keseluruhan.

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; 
}

Ini adalah bagaimana kita dapat menggunakan kata kunci "otomatis"

rahul goyal
sumber
0

Ini Ajaib adalah kemampuannya untuk mengurangi keharusan menulis kode untuk setiap Jenis Variabel yang diteruskan ke fungsi tertentu. Pertimbangkan fungsi print () yang mirip dengan Python di basis Cnya.

#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);
}
rodeone2
sumber